GEOS
3.3.8
|
00001 /********************************************************************** 00002 * $Id: OffsetSegmentString.h 3301 2011-04-27 09:42:31Z strk $ 00003 * 00004 * GEOS - Geometry Engine Open Source 00005 * http://geos.refractions.net 00006 * 00007 * Copyright (C) 2011 Sandro Santilli <strk@keybit.net> 00008 * Copyright (C) 2007 Refractions Research Inc. 00009 * 00010 * This is free software; you can redistribute and/or modify it under 00011 * the terms of the GNU Lesser General Public Licence as published 00012 * by the Free Software Foundation. 00013 * See the COPYING file for more information. 00014 * 00015 ********************************************************************** 00016 * 00017 * Last port: operation/buffer/OffsetSegmentString.java r378 (JTS-1.12) 00018 * 00019 **********************************************************************/ 00020 00021 #ifndef GEOS_OP_BUFFER_OFFSETSEGMENTSTRING_H 00022 #define GEOS_OP_BUFFER_OFFSETSEGMENTSTRING_H 00023 00024 #include <geos/geom/Coordinate.h> // for inlines 00025 #include <geos/geom/CoordinateSequence.h> // for inlines 00026 #include <geos/geom/CoordinateArraySequence.h> // for composition 00027 #include <geos/geom/PrecisionModel.h> // for inlines 00028 00029 #include <vector> 00030 #include <memory> 00031 #include <cassert> 00032 00033 namespace geos { 00034 namespace operation { // geos.operation 00035 namespace buffer { // geos.operation.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 // don't add duplicate (or near-duplicate) points 00123 if (isRedundant(bufPt)) 00124 { 00125 return; 00126 } 00127 // we ask to allow repeated as we checked this ourself 00128 // (JTS uses a vector for ptList, not a CoordinateSequence, 00129 // we should do the same) 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 // we ask to allow repeated as we checked this ourself 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 } // namespace geos.operation.buffer 00194 } // namespace geos.operation 00195 } // namespace geos 00196 00197 00198 #endif // ndef GEOS_OP_BUFFER_OFFSETSEGMENTSTRING_H 00199