OffsetSegmentString.h

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 

Generated on 10 Sep 2013 for GEOS by  doxygen 1.4.7