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