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