[QGIS Commit] r11623 - in trunk/qgis/src/analysis: . vector

svn_qgis at osgeo.org svn_qgis at osgeo.org
Fri Sep 11 02:33:31 EDT 2009


Author: mhugent
Date: 2009-09-11 02:33:30 -0400 (Fri, 11 Sep 2009)
New Revision: 11623

Modified:
   trunk/qgis/src/analysis/CMakeLists.txt
   trunk/qgis/src/analysis/vector/qgsgeometryanalyzer.cpp
   trunk/qgis/src/analysis/vector/qgsgeometryanalyzer.h
Log:
Added buffering method to qgsgeometryanalyzer

Modified: trunk/qgis/src/analysis/CMakeLists.txt
===================================================================
--- trunk/qgis/src/analysis/CMakeLists.txt	2009-09-11 06:20:04 UTC (rev 11622)
+++ trunk/qgis/src/analysis/CMakeLists.txt	2009-09-11 06:33:30 UTC (rev 11623)
@@ -97,7 +97,7 @@
 
 # Added by Tim to install headers
 
-SET(QGIS_ANALYSIS_HDRS
+SET(QGIS_ANALYSIS_HDRS vector/qgsgeometryanalyzer.h
 )
 
 INSTALL(CODE "MESSAGE(\"Installing ANALYSIS headers...\")")

Modified: trunk/qgis/src/analysis/vector/qgsgeometryanalyzer.cpp
===================================================================
--- trunk/qgis/src/analysis/vector/qgsgeometryanalyzer.cpp	2009-09-11 06:20:04 UTC (rev 11622)
+++ trunk/qgis/src/analysis/vector/qgsgeometryanalyzer.cpp	2009-09-11 06:33:30 UTC (rev 11623)
@@ -26,6 +26,7 @@
 #include "qgsvectorfilewriter.h"
 #include "qgsvectordataprovider.h"
 #include "qgsdistancearea.h"
+#include <QProgressDialog>
 
 
 
@@ -607,3 +608,157 @@
     return pointList;
     */
 }
+
+bool QgsGeometryAnalyzer::buffer( QgsVectorLayer* layer, const QString& shapefileName, double bufferDistance, \
+                                  bool onlySelectedFeatures, bool dissolve, int bufferDistanceField, QProgressDialog* p )
+{
+  if ( !layer )
+  {
+    return false;
+  }
+
+  QgsVectorDataProvider* dp = layer->dataProvider();
+  if ( !dp )
+  {
+    return false;
+  }
+
+  QGis::WkbType outputType = QGis::WKBPolygon;
+  if ( dissolve )
+  {
+    outputType = QGis::WKBMultiPolygon;
+  }
+  const QgsCoordinateReferenceSystem crs = layer->srs();
+
+  QgsVectorFileWriter vWriter( shapefileName, dp->encoding(), dp->fields(), outputType, &crs );
+  QgsFeature currentFeature;
+  QgsGeometry* dissolveGeometry; //dissolve geometry (if dissolve enabled)
+
+  //take only selection
+  if ( onlySelectedFeatures )
+  {
+    //use QgsVectorLayer::featureAtId
+    const QgsFeatureIds selection = layer->selectedFeaturesIds();
+    if ( p )
+    {
+      p->setMaximum( selection.size() );
+    }
+
+    int processedFeatures = 0;
+    QgsFeatureIds::const_iterator it = selection.constBegin();
+    for ( ; it != selection.constEnd(); ++it )
+    {
+      if ( p )
+      {
+        p->setValue( processedFeatures );
+      }
+
+      if ( p && p->wasCanceled() )
+      {
+        break;
+      }
+      if ( !layer->featureAtId( *it, currentFeature, true, true ) )
+      {
+        continue;
+      }
+      bufferFeature( currentFeature, processedFeatures, &vWriter, dissolve, &dissolveGeometry, bufferDistance, bufferDistanceField );
+      ++processedFeatures;
+    }
+
+    if ( p )
+    {
+      p->setValue( selection.size() );
+    }
+  }
+  //take all features
+  else
+  {
+    layer->select( layer->pendingAllAttributesList(), QgsRectangle(), true, false );
+
+
+    int featureCount = layer->featureCount();
+    if ( p )
+    {
+      p->setMaximum( featureCount );
+    }
+    int processedFeatures = 0;
+
+    while ( layer->nextFeature( currentFeature ) )
+    {
+      if ( p )
+      {
+        p->setValue( processedFeatures );
+      }
+      if ( p && p->wasCanceled() )
+      {
+        break;
+      }
+      bufferFeature( currentFeature, processedFeatures, &vWriter, dissolve, &dissolveGeometry, bufferDistance, bufferDistanceField );
+      ++processedFeatures;
+    }
+    if ( p )
+    {
+      p->setValue( featureCount );
+    }
+  }
+
+  if ( dissolve )
+  {
+    QgsFeature dissolveFeature;
+    dissolveFeature.setGeometry( dissolveGeometry );
+    vWriter.addFeature( dissolveFeature );
+  }
+  return true;
+}
+
+void QgsGeometryAnalyzer::bufferFeature( QgsFeature& f, int nProcessedFeatures, QgsVectorFileWriter* vfw, bool dissolve, \
+    QgsGeometry** dissolveGeometry, double bufferDistance, int bufferDistanceField )
+{
+  double currentBufferDistance;
+  QgsGeometry* featureGeometry = f.geometry();
+  QgsGeometry* tmpGeometry = 0;
+  QgsGeometry* bufferGeometry = 0;
+
+  if ( !featureGeometry )
+  {
+    return;
+  }
+
+  //create buffer
+  if ( bufferDistanceField == -1 )
+  {
+    currentBufferDistance = bufferDistance;
+  }
+  else
+  {
+    currentBufferDistance = f.attributeMap()[bufferDistanceField].toDouble();
+  }
+  bufferGeometry = featureGeometry->buffer( currentBufferDistance, 5 );
+
+  if ( dissolve )
+  {
+    if ( nProcessedFeatures == 0 )
+    {
+      *dissolveGeometry = bufferGeometry;
+    }
+    else
+    {
+      tmpGeometry = *dissolveGeometry;
+      *dissolveGeometry = ( *dissolveGeometry )->combine( bufferGeometry );
+      delete tmpGeometry;
+      delete bufferGeometry;
+    }
+  }
+  else //dissolve
+  {
+    QgsFeature newFeature;
+    newFeature.setGeometry( bufferGeometry );
+    newFeature.setAttributeMap( f.attributeMap() );
+
+    //add it to vector file writer
+    if ( vfw )
+    {
+      vfw->addFeature( newFeature );
+    }
+  }
+}

Modified: trunk/qgis/src/analysis/vector/qgsgeometryanalyzer.h
===================================================================
--- trunk/qgis/src/analysis/vector/qgsgeometryanalyzer.h	2009-09-11 06:20:04 UTC (rev 11622)
+++ trunk/qgis/src/analysis/vector/qgsgeometryanalyzer.h	2009-09-11 06:33:30 UTC (rev 11623)
@@ -26,7 +26,10 @@
 #include "qgsfield.h"
 #include "qgsdistancearea.h"
 
+class QgsVectorFileWriter;
+class QProgressDialog;
 
+
 /** \ingroup analysis
  * The QGis class provides vector geometry analysis functions
  */
@@ -35,73 +38,86 @@
 {
   public:
 
-    /** 
-     * Convert a vector layer from single part geometry 
-     * to multipart geometry for a given field 
+    /**
+     * Convert a vector layer from single part geometry
+     * to multipart geometry for a given field
      *
      * */
     bool singlepartsToMultipart( QgsVectorLayer* layer,
-        const QString& shapefileName,
-        const QString& fileEncoding,
-        const int fieldIndex );
+                                 const QString& shapefileName,
+                                 const QString& fileEncoding,
+                                 const int fieldIndex );
 
-    /** 
+    /**
      * Convert multipart features to multiple singlepart features. Creates
      * simple polygons and lines.
      */
     bool multipartToSingleparts( QgsVectorLayer* layer,
-        const QString& shapefileName,
-        const QString& fileEncoding );
+                                 const QString& shapefileName,
+                                 const QString& fileEncoding );
 
-    /** 
+    /**
      * Extract nodes from line and polygon vector layers and output them as
      * points.
      * */
     bool extractNodes( QgsVectorLayer* layer,
-        const QString& shapefileName,
-        const QString& fileEncoding );
+                       const QString& shapefileName,
+                       const QString& fileEncoding );
 
     /**
      * Convert polygon features to line features. Multipart polygons are
      * converted to multiple singlepart lines.
      */
     bool polygonsToLines( QgsVectorLayer* layer,
-        const QString& shapefileName,
-        const QString& fileEncoding );
-        
+                          const QString& shapefileName,
+                          const QString& fileEncoding );
+
     /**
      * Add vector layer geometry info to point (XCOORD, YCOORD), line (LENGTH),
      * or polygon (AREA, PERIMETER) layer.
      */
     bool exportGeometryInformation( QgsVectorLayer* layer,
-        const QString& shapefileName,
-        const QString& fileEncoding );
-    
+                                    const QString& shapefileName,
+                                    const QString& fileEncoding );
+
     /**
      * Simplify (generalise) line or polygon vector layers using (a modified)
      * Douglas-Peucker algorithm.
      */
     bool simplifyGeometry( QgsVectorLayer* layer,
-        const QString shapefileName,
-        const QString fileEncoding,
-        const double tolerance );
+                           const QString shapefileName,
+                           const QString fileEncoding,
+                           const double tolerance );
 
     /**
      * Calculate the true centroids, or 'center of mass' for each polygon in an
      * input polygon layer.
      */
     bool polygonCentroids( QgsVectorLayer* layer,
-        const QString& shapefileName,
-        const QString& fileEncoding );
+                           const QString& shapefileName,
+                           const QString& fileEncoding );
 
     /**
-     * Create a polygon based on the extents of all features (or all 
+     * Create a polygon based on the extents of all features (or all
      * selected features if applicable) and write it out to a shp.
      */
     bool layerExtent( QgsVectorLayer* layer,
-        const QString& shapefileName,
-        const QString& fileEncoding );
-                             
+                      const QString& shapefileName,
+                      const QString& fileEncoding );
+
+    /**Create buffers for a vector layer and write it to a new shape file
+      @param layer input vector layer
+      @param shapefileName path to the output shp
+      @param fileEncoding encoding of the output file
+      @param bufferDistance distance for buffering (if no buffer field is specified)
+      @param onlySelectedFeatures if true, only selected features are considered, else all the features
+      @param dissolve if true, merge all the buffers to a big multipolygon
+      @param bufferDistanceField index of the attribute field that contains the buffer distance (or -1 if all features have the same buffer distance)
+      @param p progress dialog (or 0 if no progress dialog is to be shown)
+      @note: added in version 1.3*/
+    bool buffer( QgsVectorLayer* layer, const QString& shapefileName, double bufferDistance, \
+                 bool onlySelectedFeatures = false, bool dissolve = false, int bufferDistanceField = -1, QProgressDialog* p = 0 );
+
   private:
 
     QList<double> simpleMeasure( QgsGeometry* geometry );
@@ -112,6 +128,9 @@
     QgsGeometry* extractAsMulti( QgsGeometry* geometry );
     QgsGeometry* convertGeometry( QgsGeometry* geometry );
     QList<QgsPoint> extractPoints( QgsGeometry* geometry );
+    /**Helper function to buffer an individual feature*/
+    void bufferFeature( QgsFeature& f, int nProcessedFeatures, QgsVectorFileWriter* vfw, bool dissolve, QgsGeometry** dissolveGeometry, \
+                        double bufferDistance, int bufferDistanceField );
 
 };
 #endif //QGSVECTORANALYZER



More information about the QGIS-commit mailing list