00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef GEOS_OP_BUFFER_OFFSETSEGMENTSTRING_H
00022 #define GEOS_OP_BUFFER_OFFSETSEGMENTSTRING_H
00023
00024 #include <geos/geom/Coordinate.h>
00025 #include <geos/geom/CoordinateSequence.h>
00026 #include <geos/geom/CoordinateArraySequence.h>
00027 #include <geos/geom/PrecisionModel.h>
00028
00029 #include <vector>
00030 #include <memory>
00031 #include <cassert>
00032
00033 namespace geos {
00034 namespace operation {
00035 namespace buffer {
00036
00038
00044 class OffsetSegmentString
00045 {
00046
00047 private:
00048
00049 geom::CoordinateArraySequence* ptList;
00050
00051 const geom::PrecisionModel* precisionModel;
00052
00059 double minimumVertexDistance;
00060
00068 bool isRedundant(const geom::Coordinate& pt) const
00069 {
00070 if (ptList->size() < 1)
00071 return false;
00072 const geom::Coordinate& lastPt = ptList->back();
00073 double ptDist = pt.distance(lastPt);
00074 if (ptDist < minimumVertexDistance)
00075 return true;
00076 return false;
00077 }
00078
00079
00080 public:
00081
00082 friend std::ostream& operator<< (std::ostream& os, const OffsetSegmentString& node);
00083
00084 OffsetSegmentString()
00085 :
00086 ptList(new geom::CoordinateArraySequence()),
00087 precisionModel(NULL),
00088 minimumVertexDistance (0.0)
00089 {
00090 }
00091
00092 ~OffsetSegmentString()
00093 {
00094 delete ptList;
00095 }
00096
00097 void reset()
00098 {
00099 if ( ptList ) ptList->clear();
00100 else ptList = new geom::CoordinateArraySequence();
00101
00102 precisionModel = NULL;
00103 minimumVertexDistance = 0.0;
00104 }
00105
00106 void setPrecisionModel(const geom::PrecisionModel* nPrecisionModel)
00107 {
00108 precisionModel = nPrecisionModel;
00109 }
00110
00111 void setMinimumVertexDistance(double nMinVertexDistance)
00112 {
00113 minimumVertexDistance = nMinVertexDistance;
00114 }
00115
00116 void addPt(const geom::Coordinate& pt)
00117 {
00118 assert(precisionModel);
00119
00120 geom::Coordinate bufPt = pt;
00121 precisionModel->makePrecise(bufPt);
00122
00123 if (isRedundant(bufPt))
00124 {
00125 return;
00126 }
00127
00128
00129
00130 ptList->add(bufPt, true);
00131 }
00132
00133 void addPts(const geom::CoordinateSequence& pts, bool isForward)
00134 {
00135 if ( isForward ) {
00136 for (size_t i=0, n=pts.size(); i<n; ++i) {
00137 addPt(pts[i]);
00138 }
00139 } else {
00140 for (size_t i=pts.size(); i>0; --i) {
00141 addPt(pts[i-1]);
00142 }
00143 }
00144 }
00145
00147
00149 void closeRing()
00150 {
00151 if (ptList->size() < 1) return;
00152 const geom::Coordinate& startPt = ptList->front();
00153 const geom::Coordinate& lastPt = ptList->back();
00154 if (startPt.equals(lastPt)) return;
00155
00156 ptList->add(startPt, true);
00157 }
00158
00160
00167 geom::CoordinateSequence* getCoordinates()
00168 {
00169 closeRing();
00170 geom::CoordinateSequence* ret = ptList;
00171 ptList = 0;
00172 return ret;
00173 }
00174
00175 inline int size() const { return ptList ? ptList->size() : 0 ; }
00176
00177 };
00178
00179 inline std::ostream& operator<< (std::ostream& os,
00180 const OffsetSegmentString& lst)
00181 {
00182 if ( lst.ptList )
00183 {
00184 os << *(lst.ptList);
00185 }
00186 else
00187 {
00188 os << "empty (consumed?)";
00189 }
00190 return os;
00191 }
00192
00193 }
00194 }
00195 }
00196
00197
00198 #endif // ndef GEOS_OP_BUFFER_OFFSETSEGMENTSTRING_H
00199