[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