GEOS  3.4.2
OffsetSegmentString.h
1 /**********************************************************************
2  *
3  * GEOS - Geometry Engine Open Source
4  * http://geos.osgeo.org
5  *
6  * Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
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 
37 //
44 {
45 
46 private:
47 
49 
50  const geom::PrecisionModel* precisionModel;
51 
58  double minimumVertexDistance;
59 
67  bool isRedundant(const geom::Coordinate& pt) const
68  {
69  if (ptList->size() < 1)
70  return false;
71  const geom::Coordinate& lastPt = ptList->back();
72  double ptDist = pt.distance(lastPt);
73  if (ptDist < minimumVertexDistance)
74  return true;
75  return false;
76  }
77 
78 
79 public:
80 
81  friend std::ostream& operator<< (std::ostream& os, const OffsetSegmentString& node);
82 
84  :
85  ptList(new geom::CoordinateArraySequence()),
86  precisionModel(NULL),
87  minimumVertexDistance (0.0)
88  {
89  }
90 
92  {
93  delete ptList;
94  }
95 
96  void reset()
97  {
98  if ( ptList ) ptList->clear();
99  else ptList = new geom::CoordinateArraySequence();
100 
101  precisionModel = NULL;
102  minimumVertexDistance = 0.0;
103  }
104 
105  void setPrecisionModel(const geom::PrecisionModel* nPrecisionModel)
106  {
107  precisionModel = nPrecisionModel;
108  }
109 
110  void setMinimumVertexDistance(double nMinVertexDistance)
111  {
112  minimumVertexDistance = nMinVertexDistance;
113  }
114 
115  void addPt(const geom::Coordinate& pt)
116  {
117  assert(precisionModel);
118 
119  geom::Coordinate bufPt = pt;
120  precisionModel->makePrecise(bufPt);
121  // don't add duplicate (or near-duplicate) points
122  if (isRedundant(bufPt))
123  {
124  return;
125  }
126  // we ask to allow repeated as we checked this ourself
127  // (JTS uses a vector for ptList, not a CoordinateSequence,
128  // we should do the same)
129  ptList->add(bufPt, true);
130  }
131 
132  void addPts(const geom::CoordinateSequence& pts, bool isForward)
133  {
134  if ( isForward ) {
135  for (size_t i=0, n=pts.size(); i<n; ++i) {
136  addPt(pts[i]);
137  }
138  } else {
139  for (size_t i=pts.size(); i>0; --i) {
140  addPt(pts[i-1]);
141  }
142  }
143  }
144 
146  //
148  void closeRing()
149  {
150  if (ptList->size() < 1) return;
151  const geom::Coordinate& startPt = ptList->front();
152  const geom::Coordinate& lastPt = ptList->back();
153  if (startPt.equals(lastPt)) return;
154  // we ask to allow repeated as we checked this ourself
155  ptList->add(startPt, true);
156  }
157 
159  //
167  {
168  closeRing();
169  geom::CoordinateSequence* ret = ptList;
170  ptList = 0;
171  return ret;
172  }
173 
174  inline size_t size() const { return ptList ? ptList->size() : 0 ; }
175 
176 };
177 
178 inline std::ostream& operator<< (std::ostream& os,
179  const OffsetSegmentString& lst)
180 {
181  if ( lst.ptList )
182  {
183  os << *(lst.ptList);
184  }
185  else
186  {
187  os << "empty (consumed?)";
188  }
189  return os;
190 }
191 
192 } // namespace geos.operation.buffer
193 } // namespace geos.operation
194 } // namespace geos
195 
196 
197 #endif // ndef GEOS_OP_BUFFER_OFFSETSEGMENTSTRING_H
198 
The default implementation of CoordinateSequence.
Definition: CoordinateArraySequence.h:37
Coordinate is the lightweight class used to store coordinates.
Definition: Coordinate.h:60
A dynamic list of the vertices in a constructed offset curve.
Definition: OffsetSegmentString.h:43
const Coordinate & back() const
Return last Coordinate in the sequence.
Definition: CoordinateSequence.h:88
Specifies the precision model of the Coordinate in a Geometry.
Definition: PrecisionModel.h:87
void closeRing()
Check that points are a ring.
Definition: OffsetSegmentString.h:148
geom::CoordinateSequence * getCoordinates()
Get coordinates by taking ownership of them.
Definition: OffsetSegmentString.h:166
void add(const Coordinate &c)
Add a Coordinate to the list.
bool equals(const Coordinate &other) const
2D only
double makePrecise(double val) const
Rounds a numeric value to the PrecisionModel grid.
double distance(const Coordinate &p) const
The internal representation of a list of coordinates inside a Geometry.
Definition: CoordinateSequence.h:59
void clear()
Reset this CoordinateArraySequence to the empty state.
Definition: CoordinateArraySequence.h:78
const Coordinate & front() const
Return first Coordinate in the sequence.
Definition: CoordinateSequence.h:93