GEOS  3.3.3
OffsetSegmentString.h
1 /**********************************************************************
2  * $Id: OffsetSegmentString.h 3301 2011-04-27 09:42:31Z strk $
3  *
4  * GEOS - Geometry Engine Open Source
5  * http://geos.refractions.net
6  *
7  * Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
8  * Copyright (C) 2007 Refractions Research Inc.
9  *
10  * This is free software; you can redistribute and/or modify it under
11  * the terms of the GNU Lesser General Public Licence as published
12  * by the Free Software Foundation.
13  * See the COPYING file for more information.
14  *
15  **********************************************************************
16  *
17  * Last port: operation/buffer/OffsetSegmentString.java r378 (JTS-1.12)
18  *
19  **********************************************************************/
20 
21 #ifndef GEOS_OP_BUFFER_OFFSETSEGMENTSTRING_H
22 #define GEOS_OP_BUFFER_OFFSETSEGMENTSTRING_H
23 
24 #include <geos/geom/Coordinate.h> // for inlines
25 #include <geos/geom/CoordinateSequence.h> // for inlines
26 #include <geos/geom/CoordinateArraySequence.h> // for composition
27 #include <geos/geom/PrecisionModel.h> // for inlines
28 
29 #include <vector>
30 #include <memory>
31 #include <cassert>
32 
33 namespace geos {
34 namespace operation { // geos.operation
35 namespace buffer { // geos.operation.buffer
36 
38 //
45 {
46 
47 private:
48 
50 
51  const geom::PrecisionModel* precisionModel;
52 
59  double minimumVertexDistance;
60 
68  bool isRedundant(const geom::Coordinate& pt) const
69  {
70  if (ptList->size() < 1)
71  return false;
72  const geom::Coordinate& lastPt = ptList->back();
73  double ptDist = pt.distance(lastPt);
74  if (ptDist < minimumVertexDistance)
75  return true;
76  return false;
77  }
78 
79 
80 public:
81 
82  friend std::ostream& operator<< (std::ostream& os, const OffsetSegmentString& node);
83 
85  :
86  ptList(new geom::CoordinateArraySequence()),
87  precisionModel(NULL),
88  minimumVertexDistance (0.0)
89  {
90  }
91 
93  {
94  delete ptList;
95  }
96 
97  void reset()
98  {
99  if ( ptList ) ptList->clear();
100  else ptList = new geom::CoordinateArraySequence();
101 
102  precisionModel = NULL;
103  minimumVertexDistance = 0.0;
104  }
105 
106  void setPrecisionModel(const geom::PrecisionModel* nPrecisionModel)
107  {
108  precisionModel = nPrecisionModel;
109  }
110 
111  void setMinimumVertexDistance(double nMinVertexDistance)
112  {
113  minimumVertexDistance = nMinVertexDistance;
114  }
115 
116  void addPt(const geom::Coordinate& pt)
117  {
118  assert(precisionModel);
119 
120  geom::Coordinate bufPt = pt;
121  precisionModel->makePrecise(bufPt);
122  // don't add duplicate (or near-duplicate) points
123  if (isRedundant(bufPt))
124  {
125  return;
126  }
127  // we ask to allow repeated as we checked this ourself
128  // (JTS uses a vector for ptList, not a CoordinateSequence,
129  // we should do the same)
130  ptList->add(bufPt, true);
131  }
132 
133  void addPts(const geom::CoordinateSequence& pts, bool isForward)
134  {
135  if ( isForward ) {
136  for (size_t i=0, n=pts.size(); i<n; ++i) {
137  addPt(pts[i]);
138  }
139  } else {
140  for (size_t i=pts.size(); i>0; --i) {
141  addPt(pts[i-1]);
142  }
143  }
144  }
145 
147  //
149  void closeRing()
150  {
151  if (ptList->size() < 1) return;
152  const geom::Coordinate& startPt = ptList->front();
153  const geom::Coordinate& lastPt = ptList->back();
154  if (startPt.equals(lastPt)) return;
155  // we ask to allow repeated as we checked this ourself
156  ptList->add(startPt, true);
157  }
158 
160  //
168  {
169  closeRing();
170  geom::CoordinateSequence* ret = ptList;
171  ptList = 0;
172  return ret;
173  }
174 
175  inline int size() const { return ptList ? ptList->size() : 0 ; }
176 
177 };
178 
179 inline std::ostream& operator<< (std::ostream& os,
180  const OffsetSegmentString& lst)
181 {
182  if ( lst.ptList )
183  {
184  os << *(lst.ptList);
185  }
186  else
187  {
188  os << "empty (consumed?)";
189  }
190  return os;
191 }
192 
193 } // namespace geos.operation.buffer
194 } // namespace geos.operation
195 } // namespace geos
196 
197 
198 #endif // ndef GEOS_OP_BUFFER_OFFSETSEGMENTSTRING_H
199