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