1 /**********************************************************************
2 *
3 * GEOS - Geometry Engine Open Source
4 * http://geos.osgeo.org
5 *
6 * Copyright (C) 2009-2011 Sandro Santilli <strk@kbt.io>
7 * Copyright (C) 2005-2007 Refractions Research Inc.
8 * Copyright (C) 2001-2002 Vivid Solutions Inc.
9 *
10 * This is free software; you can redistribute and/or modify it under
11 * the terms of the GNU Lesser General Public Licence as published
12 * by the Free Software Foundation.
13 * See the COPYING file for more information.
14 *
15 **********************************************************************
16 *
17 * Last port: operation/buffer/BufferOp.java r378 (JTS-1.12)
18 *
19 **********************************************************************/
20
21 #ifndef GEOS_OP_BUFFER_BUFFEROP_H
22 #define GEOS_OP_BUFFER_BUFFEROP_H
23
24 #include <geos/export.h>
25 #include <geos/operation/buffer/BufferParameters.h> // for enum values
26
27 #include <geos/util/TopologyException.h> // for composition
28
29 #ifdef _MSC_VER
30 #pragma warning(push)
31 #pragma warning(disable: 4251) // warning C4251: needs to have dll-interface to be used by clients of class
32 #endif
33
34 // Forward declarations
35 namespace geos {
36 namespace geom {
37 class PrecisionModel;
38 class Geometry;
39 }
40 }
41
42 namespace geos {
43 namespace operation { // geos.operation
44 namespace buffer { // geos.operation.buffer
45
46 /**
47 * \class BufferOp
48 *
49 * \brief
50 * Computes the buffer of a geometry, for both positive and negative
51 * buffer distances.
52 *
53 * In GIS, the positive (or negative) buffer of a geometry is defined as
54 * the Minkowski sum (or difference) of the geometry
55 * with a circle with radius equal to the absolute value of the buffer
56 * distance.
57 * In the CAD/CAM world buffers are known as *offset curves*.
58 * In morphological analysis the operation of positive and negative buffering
59 * is referred to as *erosion* and *dilation*.
60 *
61 * The buffer operation always returns a polygonal result.
62 * The negative or zero-distance buffer of lines and points is always
63 * an empty Polygon.
64 *
65 * Since true buffer curves may contain circular arcs,
66 * computed buffer polygons can only be approximations to the true geometry.
67 * The user can control the accuracy of the curve approximation by specifying
68 * the number of linear segments with which to approximate a curve.
69 *
70 * The end cap style of a linear buffer may be specified.
71 * The following end cap styles are supported:
72 * - CAP_ROUND - the usual round end caps
73 * - CAP_BUTT - end caps are truncated flat at the line ends
74 * - CAP_SQUARE - end caps are squared off at the buffer distance
75 * beyond the line ends
76 *
77 */
78 class GEOS_DLL BufferOp {
79
80
81 private:
82
83 /** \brief
84 * A number of digits of precision which leaves some computational "headroom"
85 * for floating point operations.
86 *
87 * This value should be less than the decimal precision of double-precision values (16).
88 */
89 static const int MAX_PRECISION_DIGITS = 12;
90
91 /**
92 * Compute a reasonable scale factor to limit the precision of
93 * a given combination of Geometry and buffer distance.
94 * The scale factor is based on a heuristic.
95 *
96 * @param g the Geometry being buffered
97 *
98 * @param distance the buffer distance
99 *
100 * @param maxPrecisionDigits the mzx # of digits that should be
101 * allowed by the precision determined by the
102 * computed scale factor
103 *
104 * @return a scale factor that allows a reasonable amount of
105 * precision for the buffer computation
106 */
107 static double precisionScaleFactor(const geom::Geometry* g,
108 double distance, int maxPrecisionDigits);
109
110 const geom::Geometry* argGeom;
111
112 util::TopologyException saveException;
113
114 double distance;
115
116 //int quadrantSegments;
117 //int endCapStyle;
118 BufferParameters bufParams;
119
120 geom::Geometry* resultGeometry;
121
122 void computeGeometry();
123
124 void bufferOriginalPrecision();
125
126 void bufferReducedPrecision(int precisionDigits);
127
128 void bufferReducedPrecision();
129
130 void bufferFixedPrecision(const geom::PrecisionModel& fixedPM);
131
132 public:
133
134 enum {
135 /// Specifies a round line buffer end cap style.
136 /// @deprecated use BufferParameters
137 CAP_ROUND = BufferParameters::CAP_ROUND,
138
139 /// Specifies a butt (or flat) line buffer end cap style.
140 /// @deprecated use BufferParameters
141 CAP_BUTT = BufferParameters::CAP_FLAT,
142
143 /// Specifies a square line buffer end cap style.
144 /// @deprecated use BufferParameters
145 CAP_SQUARE = BufferParameters::CAP_SQUARE
146 };
147
148 /** \brief
149 * Computes the buffer for a geometry for a given buffer distance
150 * and accuracy of approximation.
151 *
152 * @param g the geometry to buffer
153 * @param distance the buffer distance
154 * @param quadrantSegments the number of segments used to
155 * approximate a quarter circle
156 * @param endCapStyle line buffer end cap style (default: BufferParameters::CAP_ROUND)
157 * @return the buffer of the input geometry
158 *
159 */
160 static geom::Geometry* bufferOp(const geom::Geometry* g,
161 double distance,
162 int quadrantSegments =
163 BufferParameters::DEFAULT_QUADRANT_SEGMENTS,
164 int endCapStyle = BufferParameters::CAP_ROUND);
165
166 /** \brief
167 * Initializes a buffer computation for the given geometry.
168 *
169 * @param g the geometry to buffer
170 */
BufferOp(const geom::Geometry * g)171 BufferOp(const geom::Geometry* g)
172 :
173 argGeom(g),
174 bufParams(),
175 resultGeometry(nullptr)
176 {
177 }
178
179 /** \brief
180 * Initializes a buffer computation for the given geometry
181 * with the given set of parameters.
182 *
183 * @param g the geometry to buffer
184 * @param params the buffer parameters to use. This class will
185 * copy it to private memory.
186 */
BufferOp(const geom::Geometry * g,const BufferParameters & params)187 BufferOp(const geom::Geometry* g, const BufferParameters& params)
188 :
189 argGeom(g),
190 bufParams(params),
191 resultGeometry(nullptr)
192 {
193 }
194
195 /** \brief
196 * Specifies the end cap style of the generated buffer.
197 *
198 * The styles supported are CAP_ROUND, CAP_BUTT, and CAP_SQUARE.
199 * The default is CAP_ROUND.
200 *
201 * @param nEndCapStyle the end cap style to specify
202 */
203 inline void setEndCapStyle(int nEndCapStyle);
204
205 /** \brief
206 * Sets the number of segments used to approximate a angle fillet
207 *
208 * @param nQuadrantSegments the number of segments in a fillet for a quadrant
209 */
210 inline void setQuadrantSegments(int nQuadrantSegments);
211
212 /** \brief
213 * Sets whether the computed buffer should be single-sided.
214 *
215 * A single-sided buffer is constructed on only one side
216 * of each input line.
217 *
218 * The side used is determined by the sign of the buffer distance:
219 * - a positive distance indicates the left-hand side
220 * - a negative distance indicates the right-hand side
221 *
222 * The single-sided buffer of point geometries is
223 * the same as the regular buffer.
224 *
225 * The End Cap Style for single-sided buffers is
226 * always ignored,
227 * and forced to the equivalent of `CAP_FLAT`.
228 *
229 * @param isSingleSided `true` if a single-sided buffer
230 * should be constructed
231 */
232 inline void setSingleSided(bool isSingleSided);
233
234 /** \brief
235 * Returns the buffer computed for a geometry for a given buffer
236 * distance.
237 *
238 * @param nDistance the buffer distance
239 * @return the buffer of the input geometry
240 */
241 geom::Geometry* getResultGeometry(double nDistance);
242
243 };
244
245 // BufferOp inlines
246 void
setQuadrantSegments(int q)247 BufferOp::setQuadrantSegments(int q)
248 {
249 bufParams.setQuadrantSegments(q);
250 }
251
252 void
setEndCapStyle(int s)253 BufferOp::setEndCapStyle(int s)
254 {
255 bufParams.setEndCapStyle((BufferParameters::EndCapStyle)s);
256 }
257
258 void
setSingleSided(bool isSingleSided)259 BufferOp::setSingleSided(bool isSingleSided)
260 {
261 bufParams.setSingleSided(isSingleSided);
262 }
263
264 } // namespace geos::operation::buffer
265 } // namespace geos::operation
266 } // namespace geos
267
268 #ifdef _MSC_VER
269 #pragma warning(pop)
270 #endif
271
272 #endif // ndef GEOS_OP_BUFFER_BUFFEROP_H
273
274