/src/geos/include/geos/operation/buffer/OffsetCurveBuilder.h
Line | Count | Source |
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) 2006-2007 Refractions Research Inc. |
8 | | * |
9 | | * This is free software; you can redistribute and/or modify it under |
10 | | * the terms of the GNU Lesser General Public Licence as published |
11 | | * by the Free Software Foundation. |
12 | | * See the COPYING file for more information. |
13 | | * |
14 | | ********************************************************************** |
15 | | * |
16 | | * Last port: operation/buffer/OffsetCurveBuilder.java r378 (JTS-1.12) |
17 | | * |
18 | | **********************************************************************/ |
19 | | |
20 | | #pragma once |
21 | | |
22 | | #include <geos/export.h> |
23 | | |
24 | | #include <geos/operation/buffer/BufferParameters.h> // for composition |
25 | | #include <geos/operation/buffer/OffsetSegmentGenerator.h> |
26 | | |
27 | | #include <vector> |
28 | | #include <memory> // for unique_ptr |
29 | | |
30 | | #ifdef _MSC_VER |
31 | | #pragma warning(push) |
32 | | #pragma warning(disable: 4251) // warning C4251: needs to have dll-interface to be used by clients of class |
33 | | #endif |
34 | | |
35 | | // Forward declarations |
36 | | namespace geos { |
37 | | namespace geom { |
38 | | class CoordinateSequence; |
39 | | class PrecisionModel; |
40 | | } |
41 | | } |
42 | | |
43 | | namespace geos { |
44 | | namespace operation { // geos.operation |
45 | | namespace buffer { // geos.operation.buffer |
46 | | |
47 | | /** |
48 | | * \class OffsetCurveBuilder |
49 | | * |
50 | | * \brief |
51 | | * Computes the raw offset curve for a |
52 | | * single Geometry component (ring, line or point). |
53 | | * |
54 | | * A raw offset curve line is not noded - |
55 | | * it may contain self-intersections (and usually will). |
56 | | * The final buffer polygon is computed by forming a topological graph |
57 | | * of all the noded raw curves and tracing outside contours. |
58 | | * The points in the raw curve are rounded to a given PrecisionModel. |
59 | | * |
60 | | * Note: this may not produce correct results if the input |
61 | | * contains repeated or invalid points. |
62 | | * Repeated points should be removed before calling. |
63 | | * See removeRepeatedAndInvalidPoints. |
64 | | */ |
65 | | class GEOS_DLL OffsetCurveBuilder { |
66 | | using CoordinateSequence = geos::geom::CoordinateSequence; |
67 | | using PrecisionModel = geos::geom::PrecisionModel; |
68 | | |
69 | | public: |
70 | | |
71 | | /* |
72 | | * @param nBufParams buffer parameters, this object will |
73 | | * keep a reference to the passed parameters |
74 | | * so caller must make sure the object is |
75 | | * kept alive for the whole lifetime of |
76 | | * the buffer builder. |
77 | | */ |
78 | | OffsetCurveBuilder( |
79 | | const PrecisionModel* newPrecisionModel, |
80 | | const BufferParameters& nBufParams) |
81 | 0 | : distance(0.0) |
82 | 0 | , precisionModel(newPrecisionModel) |
83 | 0 | , bufParams(nBufParams) |
84 | 0 | {} |
85 | | |
86 | | /** \brief |
87 | | * Gets the buffer parameters being used to generate the curve. |
88 | | * |
89 | | * @return the buffer parameters being used |
90 | | */ |
91 | | const BufferParameters& |
92 | | getBufferParameters() const |
93 | 0 | { |
94 | 0 | return bufParams; |
95 | 0 | } |
96 | | |
97 | | /** |
98 | | * Tests whether the offset curve for line or point geometries |
99 | | * at the given offset distance is empty (does not exist). |
100 | | * This is the case if: |
101 | | * |
102 | | * * the distance is zero, |
103 | | * * the distance is negative, except for the case of singled-sided buffers |
104 | | * |
105 | | * @param distance the offset curve distance |
106 | | * @return true if the offset curve is empty |
107 | | */ |
108 | | bool isLineOffsetEmpty(double distance); |
109 | | |
110 | | /** \brief |
111 | | * This method handles single points as well as lines. |
112 | | * |
113 | | * Lines are assumed to **not** be closed (the function will not |
114 | | * fail for closed lines, but will generate superfluous line caps). |
115 | | * |
116 | | * @param inputPts input points |
117 | | * @param distance offset distance |
118 | | * @param lineList the std::vector to which the newly created |
119 | | * CoordinateSequences will be pushed_back. |
120 | | */ |
121 | | void getLineCurve(const CoordinateSequence* inputPts, |
122 | | double distance, |
123 | | std::vector<std::unique_ptr<CoordinateSequence>>& lineList); |
124 | | |
125 | | /** |
126 | | * This method handles single points as well as LineStrings. |
127 | | * LineStrings are assumed <b>not</b> to be closed (the function will not |
128 | | * fail for closed lines, but will generate superfluous line caps). |
129 | | * |
130 | | * @param inputPts the vertices of the line to offset |
131 | | * @param pDistance the offset distance |
132 | | * |
133 | | * @return a Coordinate array representing the curve |
134 | | * or null if the curve is empty |
135 | | */ |
136 | | std::unique_ptr<CoordinateSequence> getLineCurve( |
137 | | const CoordinateSequence* inputPts, double pDistance); |
138 | | |
139 | | /** \brief |
140 | | * This method handles single points as well as lines. |
141 | | * |
142 | | * Lines are assumed to **not** be closed (the function will not |
143 | | * fail for closed lines, but will generate superfluous line caps). |
144 | | * |
145 | | * @param inputPts input points |
146 | | * @param distance offset distance |
147 | | * @param lineList the std::vector to which newly created |
148 | | * CoordinateSequences will be pushed_back. |
149 | | * Caller will be responsible to delete them. |
150 | | * @param leftSide indicates that the left side buffer will be |
151 | | * obtained/skipped |
152 | | * @param rightSide indicates that the right side buffer will |
153 | | * be obtained/skipped |
154 | | * |
155 | | * @note This is a GEOS extension. |
156 | | */ |
157 | | void getSingleSidedLineCurve(const CoordinateSequence* inputPts, |
158 | | double distance, std::vector<std::unique_ptr<CoordinateSequence>>& lineList, |
159 | | bool leftSide, bool rightSide) ; |
160 | | |
161 | | /** \brief |
162 | | * This method handles the degenerate cases of single points and lines, |
163 | | * as well as rings. |
164 | | * |
165 | | * @param inputPts input points |
166 | | * @param side a [Position](@ref geom::Position) |
167 | | * @param distance offset distance |
168 | | * @param lineList the std::vector to which CoordinateSequences will |
169 | | * be pushed_back |
170 | | */ |
171 | | void getRingCurve(const CoordinateSequence* inputPts, int side, |
172 | | double distance, |
173 | | std::vector<std::unique_ptr<CoordinateSequence>>& lineList); |
174 | | |
175 | | /** |
176 | | * This method handles the degenerate cases of single points and lines, |
177 | | * as well as valid rings. |
178 | | * |
179 | | * @param inputPts the coordinates of the ring (must not contain repeated points) |
180 | | * @param side side the side Position of the ring on which to construct the buffer line |
181 | | * @param pDistance the positive distance at which to create the offset |
182 | | * @return a Coordinate array representing the curve, |
183 | | * or null if the curve is empty |
184 | | */ |
185 | | std::unique_ptr<CoordinateSequence> getRingCurve( |
186 | | const CoordinateSequence* inputPts, |
187 | | int side, double pDistance); |
188 | | |
189 | | void getOffsetCurve(const CoordinateSequence* inputPts, |
190 | | double p_distance, |
191 | | std::vector<std::unique_ptr<CoordinateSequence>>& lineList); |
192 | | |
193 | | std::unique_ptr<CoordinateSequence> getOffsetCurve( |
194 | | const CoordinateSequence* inputPts, |
195 | | double pDistance); |
196 | | |
197 | | |
198 | | private: |
199 | | |
200 | | double distance; |
201 | | |
202 | | const PrecisionModel* precisionModel; |
203 | | |
204 | | const BufferParameters& bufParams; |
205 | | |
206 | | /** \brief |
207 | | * Use a value which results in a potential distance error which is |
208 | | * significantly less than the error due to the quadrant segment discretization. |
209 | | * |
210 | | * For QS = 8 a value of 100 is reasonable. |
211 | | * This should produce a maximum of 1% distance error. |
212 | | */ |
213 | | static const double SIMPLIFY_FACTOR; // 100.0; |
214 | | |
215 | | /** \brief |
216 | | * Computes the distance tolerance to use during input |
217 | | * line simplification. |
218 | | * |
219 | | * @param bufDistance the buffer distance |
220 | | * @return the simplification tolerance |
221 | | */ |
222 | | double simplifyTolerance(double bufDistance); |
223 | | |
224 | | void computeLineBufferCurve(const CoordinateSequence& inputPts, |
225 | | OffsetSegmentGenerator& segGen); |
226 | | |
227 | | void computeSingleSidedBufferCurve(const CoordinateSequence& inputPts, |
228 | | bool isRightSide, |
229 | | OffsetSegmentGenerator& segGen); |
230 | | |
231 | | void computeRingBufferCurve(const CoordinateSequence& inputPts, |
232 | | int side, OffsetSegmentGenerator& segGen); |
233 | | |
234 | | void computePointCurve(const geom::Coordinate& pt, |
235 | | OffsetSegmentGenerator& segGen); |
236 | | |
237 | | void computeOffsetCurve( |
238 | | const CoordinateSequence* inputPts, |
239 | | bool isRightSide, |
240 | | OffsetSegmentGenerator& segGen); |
241 | | |
242 | | |
243 | | |
244 | | // Declare type as noncopyable |
245 | | OffsetCurveBuilder(const OffsetCurveBuilder& other) = delete; |
246 | | OffsetCurveBuilder& operator=(const OffsetCurveBuilder& rhs) = delete; |
247 | | }; |
248 | | |
249 | | } // namespace geos::operation::buffer |
250 | | } // namespace geos::operation |
251 | | } // namespace geos |
252 | | |
253 | | #ifdef _MSC_VER |
254 | | #pragma warning(pop) |
255 | | #endif |
256 | | |