GEOS  3.13.1
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> computePolygonCurve(
107  const Polygon& polyGeom, double distance);
108 
109  std::unique_ptr<Geometry> computeCurve(
110  const LineString& lineGeom, double distance);
111 
112  std::vector<std::unique_ptr<OffsetCurveSection>> computeSections(
113  const LineString& lineGeom, double distance);
114 
115  std::unique_ptr<LineString> offsetSegment(
116  const CoordinateSequence* pts, double distance);
117 
118  static std::unique_ptr<Polygon> getBufferOriented(
119  const LineString& geom, double distance,
120  BufferParameters& bufParams);
121 
130  static const Polygon* extractMaxAreaPolygon(const Geometry* geom);
131 
132  void computeCurveSections(
133  const CoordinateSequence* bufferRingPts,
134  const CoordinateSequence& rawCurve,
135  std::vector<std::unique_ptr<OffsetCurveSection>>& sections);
136 
149  std::size_t matchSegments(
150  const Coordinate& raw0, const Coordinate& raw1,
151  std::size_t rawCurveIndex,
152  SegmentMCIndex& bufferSegIndex,
153  const CoordinateSequence* bufferPts,
154  std::vector<double>& rawCurvePos);
155 
156  static double segmentMatchFrac(
157  const Coordinate& p0, const Coordinate& p1,
158  const Coordinate& seg0, const Coordinate& seg1,
159  double matchDistance);
160 
172  void extractSections(
173  const CoordinateSequence* ringPts,
174  std::vector<double>& rawCurveLoc,
175  std::size_t startIndex,
176  std::vector<std::unique_ptr<OffsetCurveSection>>& sections);
177 
178  std::size_t findSectionStart(
179  const std::vector<double>& loc,
180  std::size_t end);
181 
182  std::size_t findSectionEnd(
183  const std::vector<double>& loc,
184  std::size_t start,
185  std::size_t firstStartIndex);
186 
187  static std::size_t nextIndex(std::size_t i, std::size_t size);
188  static std::size_t prevIndex(std::size_t i, std::size_t size);
189 
190 
191 public:
192 
193  // Constants
194  static constexpr int MATCH_DISTANCE_FACTOR = 10000;
195 
200  static constexpr int MIN_QUADRANT_SEGMENTS = 8;
201 
212  OffsetCurve(const Geometry& geom, double dist)
213  : inputGeom(geom)
214  , distance(dist)
215  , matchDistance(std::abs(dist)/MATCH_DISTANCE_FACTOR)
216  , geomFactory(geom.getFactory())
217  {
218  if (!std::isfinite(dist)) {
219  throw util::IllegalArgumentException("OffsetCurve distance must be a finite value");
220  }
221  };
222 
232  OffsetCurve(const Geometry& geom, double dist, BufferParameters& bp)
233  : inputGeom(geom)
234  , distance(dist)
235  , matchDistance(std::abs(dist)/MATCH_DISTANCE_FACTOR)
236  , geomFactory(geom.getFactory())
237  {
238  if (!std::isfinite(dist)) {
239  throw util::IllegalArgumentException("OffsetCurve distance must be a finite value");
240  }
241  //-- set buffer params, leaving cap style as the default CAP_ROUND
242 
247  int quadSegs = bp.getQuadrantSegments();
248  if (quadSegs < MIN_QUADRANT_SEGMENTS) {
249  quadSegs = MIN_QUADRANT_SEGMENTS;
250  }
251  bufferParams.setQuadrantSegments(quadSegs);
252 
253  bufferParams.setJoinStyle( bp.getJoinStyle());
254  bufferParams.setMitreLimit( bp.getMitreLimit());
255  };
256 
264  void setJoined(bool pIsJoined);
265 
266  static std::unique_ptr<Geometry> getCurve(
267  const Geometry& geom,
268  double dist,
269  int quadSegs,
270  BufferParameters::JoinStyle joinStyle,
271  double mitreLimit);
272 
273  static std::unique_ptr<Geometry> getCurve(
274  const Geometry& geom, double dist);
275 
284  static std::unique_ptr<Geometry> getCurveJoined(
285  const Geometry& geom, double dist);
286 
292  std::unique_ptr<Geometry> getCurve();
293 
307  static std::unique_ptr<CoordinateSequence> rawOffsetCurve(
308  const LineString& line,
309  double distance,
310  BufferParameters& bufParams);
311 
320  static std::unique_ptr<CoordinateSequence> rawOffset(
321  const LineString& line,
322  double distance);
323 
324 };
325 
326 } // namespace geos::operation::buffer
327 } // namespace geos::operation
328 } // namespace geos
329 
330 
331 
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:217
Supplies a set of utility methods for building Geometry objects from CoordinateSequence or other Geom...
Definition: GeometryFactory.h:70
Basic implementation of Geometry, constructed and destructed by GeometryFactory.
Definition: Geometry.h:197
Definition: LineString.h:66
Represents a linear polygon, which may include holes.
Definition: Polygon.h:61
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:232
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:212
Indicates one or more illegal arguments.
Definition: IllegalArgumentException.h:33
Basic namespace for all GEOS functionalities.
Definition: Angle.h:25