GEOS  3.13.0dev
OffsetCurve.h
1 /**********************************************************************
2  *
3  * GEOS - Geometry Engine Open Source
4  * http://geos.osgeo.org
5  *
6  * Copyright (C) 2021 Paul Ramsey <pramsey@cleverelephant.ca>
7  *
8  * This is free software; you can redistribute and/or modify it under
9  * the terms of the GNU Lesser General Public Licence as published
10  * by the Free Software Foundation.
11  * See the COPYING file for more information.
12  *
13  **********************************************************************/
14 
15 #pragma once
16 
17 #include <geos/export.h>
18 
19 #include <geos/operation/buffer/BufferParameters.h>
20 #include <geos/geom/GeometryFactory.h>
21 #include <geos/constants.h>
22 
23 // Forward declarations
24 namespace geos {
25 namespace geom {
26 class Coordinate;
27 class CoordinateSequence;
28 class Geometry;
29 class LineString;
30 class Polygon;
31 }
32 namespace operation {
33 namespace buffer {
34 class OffsetCurveSection;
35 class SegmentMCIndex;
36 }
37 }
38 }
39 
46 
47 namespace geos {
48 namespace operation {
49 namespace buffer {
50 
90 class GEOS_DLL OffsetCurve {
91 
92 
93 private:
94 
95  // Members
96  const Geometry& inputGeom;
97  double distance;
98  bool isJoined = false;
99 
100  BufferParameters bufferParams;
101  double matchDistance;
102  const GeometryFactory* geomFactory;
103 
104  // Methods
105 
106  std::unique_ptr<Geometry> computeCurve(
107  const LineString& lineGeom, double distance);
108 
109  std::vector<std::unique_ptr<OffsetCurveSection>> computeSections(
110  const LineString& lineGeom, double distance);
111 
112  std::unique_ptr<LineString> offsetSegment(
113  const CoordinateSequence* pts, double distance);
114 
115  static std::unique_ptr<Polygon> getBufferOriented(
116  const LineString& geom, double distance,
117  BufferParameters& bufParams);
118 
127  static const Polygon* extractMaxAreaPolygon(const Geometry* geom);
128 
129  void computeCurveSections(
130  const CoordinateSequence* bufferRingPts,
131  const CoordinateSequence& rawCurve,
132  std::vector<std::unique_ptr<OffsetCurveSection>>& sections);
133 
146  std::size_t matchSegments(
147  const Coordinate& raw0, const Coordinate& raw1,
148  std::size_t rawCurveIndex,
149  SegmentMCIndex& bufferSegIndex,
150  const CoordinateSequence* bufferPts,
151  std::vector<double>& rawCurvePos);
152 
153  static double segmentMatchFrac(
154  const Coordinate& p0, const Coordinate& p1,
155  const Coordinate& seg0, const Coordinate& seg1,
156  double matchDistance);
157 
169  void extractSections(
170  const CoordinateSequence* ringPts,
171  std::vector<double>& rawCurveLoc,
172  std::size_t startIndex,
173  std::vector<std::unique_ptr<OffsetCurveSection>>& sections);
174 
175  std::size_t findSectionStart(
176  const std::vector<double>& loc,
177  std::size_t end);
178 
179  std::size_t findSectionEnd(
180  const std::vector<double>& loc,
181  std::size_t start,
182  std::size_t firstStartIndex);
183 
184  static std::size_t nextIndex(std::size_t i, std::size_t size);
185  static std::size_t prevIndex(std::size_t i, std::size_t size);
186 
187 
188 public:
189 
190  // Constants
191  static constexpr int MATCH_DISTANCE_FACTOR = 10000;
192 
197  static constexpr int MIN_QUADRANT_SEGMENTS = 8;
198 
209  OffsetCurve(const Geometry& geom, double dist)
210  : inputGeom(geom)
211  , distance(dist)
212  , matchDistance(std::abs(dist)/MATCH_DISTANCE_FACTOR)
213  , geomFactory(geom.getFactory())
214  {
215  if (!std::isfinite(dist)) {
216  throw util::IllegalArgumentException("OffsetCurve distance must be a finite value");
217  }
218  };
219 
229  OffsetCurve(const Geometry& geom, double dist, BufferParameters& bp)
230  : inputGeom(geom)
231  , distance(dist)
232  , matchDistance(std::abs(dist)/MATCH_DISTANCE_FACTOR)
233  , geomFactory(geom.getFactory())
234  {
235  if (!std::isfinite(dist)) {
236  throw util::IllegalArgumentException("OffsetCurve distance must be a finite value");
237  }
238  //-- set buffer params, leaving cap style as the default CAP_ROUND
239 
244  int quadSegs = bp.getQuadrantSegments();
245  if (quadSegs < MIN_QUADRANT_SEGMENTS) {
246  quadSegs = MIN_QUADRANT_SEGMENTS;
247  }
248  bufferParams.setQuadrantSegments(quadSegs);
249 
250  bufferParams.setJoinStyle( bp.getJoinStyle());
251  bufferParams.setMitreLimit( bp.getMitreLimit());
252  };
253 
261  void setJoined(bool pIsJoined);
262 
263  static std::unique_ptr<Geometry> getCurve(
264  const Geometry& geom,
265  double dist,
266  int quadSegs,
267  BufferParameters::JoinStyle joinStyle,
268  double mitreLimit);
269 
270  static std::unique_ptr<Geometry> getCurve(
271  const Geometry& geom, double dist);
272 
281  static std::unique_ptr<Geometry> getCurveJoined(
282  const Geometry& geom, double dist);
283 
289  std::unique_ptr<Geometry> getCurve();
290 
304  static std::unique_ptr<CoordinateSequence> rawOffsetCurve(
305  const LineString& line,
306  double distance,
307  BufferParameters& bufParams);
308 
317  static std::unique_ptr<CoordinateSequence> rawOffset(
318  const LineString& line,
319  double distance);
320 
321 };
322 
323 } // namespace geos::operation::buffer
324 } // namespace geos::operation
325 } // namespace geos
326 
327 
328 
The internal representation of a list of coordinates inside a Geometry.
Definition: CoordinateSequence.h:56
Coordinate is the lightweight class used to store coordinates.
Definition: Coordinate.h:216
Supplies a set of utility methods for building Geometry objects from CoordinateSequence or other Geom...
Definition: GeometryFactory.h:65
Basic implementation of Geometry, constructed and destructed by GeometryFactory.
Definition: Geometry.h:186
Definition: LineString.h:65
Represents a linear polygon, which may include holes.
Definition: Polygon.h:60
Contains the parameters which describe how a buffer should be constructed.
Definition: BufferParameters.h:56
double getMitreLimit() const
Definition: BufferParameters.h:236
void setMitreLimit(double limit)
Definition: BufferParameters.h:255
JoinStyle getJoinStyle() const
Definition: BufferParameters.h:211
void setJoinStyle(JoinStyle style)
Sets the join style for outside (reflex) corners between line segments.
Definition: BufferParameters.h:226
int getQuadrantSegments() const
Definition: BufferParameters.h:137
void setQuadrantSegments(int quadSegs)
Sets the number of line segments used to approximate an angle fillet.
JoinStyle
Join styles.
Definition: BufferParameters.h:74
Definition: OffsetCurve.h:90
OffsetCurve(const Geometry &geom, double dist, BufferParameters &bp)
Definition: OffsetCurve.h:229
std::unique_ptr< Geometry > getCurve()
static std::unique_ptr< CoordinateSequence > rawOffset(const LineString &line, double distance)
static std::unique_ptr< CoordinateSequence > rawOffsetCurve(const LineString &line, double distance, BufferParameters &bufParams)
static std::unique_ptr< Geometry > getCurveJoined(const Geometry &geom, double dist)
OffsetCurve(const Geometry &geom, double dist)
Definition: OffsetCurve.h:209
Indicates one or more illegal arguments.
Definition: IllegalArgumentException.h:33
Basic namespace for all GEOS functionalities.
Definition: Angle.h:25