GEOS  3.9.1
OffsetSegmentString.h
1 /**********************************************************************
2  *
3  * GEOS - Geometry Engine Open Source
4  * http://geos.osgeo.org
5  *
6  * Copyright (C) 2011 Sandro Santilli <strk@kbt.io>
7  * Copyright (C) 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/OffsetSegmentString.java r378 (JTS-1.12)
17  *
18  **********************************************************************/
19 
20 #ifndef GEOS_OP_BUFFER_OFFSETSEGMENTSTRING_H
21 #define GEOS_OP_BUFFER_OFFSETSEGMENTSTRING_H
22 
23 #include <geos/geom/Coordinate.h> // for inlines
24 #include <geos/geom/CoordinateSequence.h> // for inlines
25 #include <geos/geom/CoordinateArraySequence.h> // for composition
26 #include <geos/geom/PrecisionModel.h> // for inlines
27 
28 #include <vector>
29 #include <memory>
30 #include <cassert>
31 
32 namespace geos {
33 namespace operation { // geos.operation
34 namespace buffer { // geos.operation.buffer
35 
44 
45 private:
46 
48 
49  const geom::PrecisionModel* precisionModel;
50 
57  double minimumVertexDistance;
58 
66  bool
67  isRedundant(const geom::Coordinate& pt) const
68  {
69  if(ptList->size() < 1) {
70  return false;
71  }
72  const geom::Coordinate& lastPt = ptList->back();
73  double ptDist = pt.distance(lastPt);
74  if(ptDist < minimumVertexDistance) {
75  return true;
76  }
77  return false;
78  }
79 
81  OffsetSegmentString& operator=(const OffsetSegmentString&) = delete;
82 
83 public:
84 
85  friend std::ostream& operator<< (std::ostream& os, const OffsetSegmentString& node);
86 
88  :
89  ptList(new geom::CoordinateArraySequence()),
90  precisionModel(nullptr),
91  minimumVertexDistance(0.0)
92  {
93  }
94 
96  {
97  delete ptList;
98  }
99 
100  void
101  reset()
102  {
103  if(ptList) {
104  ptList->clear();
105  }
106  else {
107  ptList = new geom::CoordinateArraySequence();
108  }
109 
110  precisionModel = nullptr;
111  minimumVertexDistance = 0.0;
112  }
113 
114  void
115  setPrecisionModel(const geom::PrecisionModel* nPrecisionModel)
116  {
117  precisionModel = nPrecisionModel;
118  }
119 
120  void
121  setMinimumVertexDistance(double nMinVertexDistance)
122  {
123  minimumVertexDistance = nMinVertexDistance;
124  }
125 
126  void
127  addPt(const geom::Coordinate& pt)
128  {
129  assert(precisionModel);
130 
131  geom::Coordinate bufPt = pt;
132  precisionModel->makePrecise(bufPt);
133  // don't add duplicate (or near-duplicate) points
134  if(isRedundant(bufPt)) {
135  return;
136  }
137  // we ask to allow repeated as we checked this ourself
138  // (JTS uses a vector for ptList, not a CoordinateSequence,
139  // we should do the same)
140  ptList->add(bufPt, true);
141  }
142 
143  void
144  addPts(const geom::CoordinateSequence& pts, bool isForward)
145  {
146  if(isForward) {
147  for(size_t i = 0, n = pts.size(); i < n; ++i) {
148  addPt(pts[i]);
149  }
150  }
151  else {
152  for(size_t i = pts.size(); i > 0; --i) {
153  addPt(pts[i - 1]);
154  }
155  }
156  }
157 
161  void
163  {
164  if(ptList->size() < 1) {
165  return;
166  }
167  const geom::Coordinate& startPt = ptList->front();
168  const geom::Coordinate& lastPt = ptList->back();
169  if(startPt.equals(lastPt)) {
170  return;
171  }
172  // we ask to allow repeated as we checked this ourself
173  ptList->add(startPt, true);
174  }
175 
186  {
187  closeRing();
188  geom::CoordinateSequence* ret = ptList;
189  ptList = nullptr;
190  return ret;
191  }
192 
193  inline size_t
194  size() const
195  {
196  return ptList ? ptList->size() : 0 ;
197  }
198 
199 };
200 
201 inline std::ostream&
202 operator<< (std::ostream& os,
203  const OffsetSegmentString& lst)
204 {
205  if(lst.ptList) {
206  os << *(lst.ptList);
207  }
208  else {
209  os << "empty (consumed?)";
210  }
211  return os;
212 }
213 
214 } // namespace geos.operation.buffer
215 } // namespace geos.operation
216 } // namespace geos
217 
218 
219 #endif // ndef GEOS_OP_BUFFER_OFFSETSEGMENTSTRING_H
220 
The default implementation of CoordinateSequence.
Definition: CoordinateArraySequence.h:37
void clear()
Reset this CoordinateArraySequence to the empty state.
Definition: CoordinateArraySequence.h:86
void add(const Coordinate &c)
Add a Coordinate to the list.
The internal representation of a list of coordinates inside a Geometry.
Definition: CoordinateSequence.h:58
const Coordinate & back() const
Return last Coordinate in the sequence.
Definition: CoordinateSequence.h:88
const Coordinate & front() const
Return first Coordinate in the sequence.
Definition: CoordinateSequence.h:95
Coordinate is the lightweight class used to store coordinates.
Definition: Coordinate.h:60
bool equals(const Coordinate &other) const
2D only
double distance(const Coordinate &p) const
Specifies the precision model of the Coordinate in a Geometry.
Definition: PrecisionModel.h:87
double makePrecise(double val) const
Rounds a numeric value to the PrecisionModel grid.
Definition: OffsetSegmentString.h:43
void closeRing()
Definition: OffsetSegmentString.h:162
geom::CoordinateSequence * getCoordinates()
Definition: OffsetSegmentString.h:185
Basic namespace for all GEOS functionalities.
Definition: IndexedNestedRingTester.h:26