Skip to content

Commit

Permalink
Added buffering method to qgsgeometryanalyzer
Browse files Browse the repository at this point in the history
git-svn-id: http://svn.osgeo.org/qgis/trunk@11623 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
mhugent committed Sep 11, 2009
1 parent 8858bc2 commit 2967013
Show file tree
Hide file tree
Showing 3 changed files with 202 additions and 28 deletions.
2 changes: 1 addition & 1 deletion src/analysis/CMakeLists.txt
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ INSTALL(TARGETS qgis_analysis


# Added by Tim to install headers # Added by Tim to install headers


SET(QGIS_ANALYSIS_HDRS SET(QGIS_ANALYSIS_HDRS vector/qgsgeometryanalyzer.h
) )


INSTALL(CODE "MESSAGE(\"Installing ANALYSIS headers...\")") INSTALL(CODE "MESSAGE(\"Installing ANALYSIS headers...\")")
Expand Down
155 changes: 155 additions & 0 deletions src/analysis/vector/qgsgeometryanalyzer.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "qgsvectorfilewriter.h" #include "qgsvectorfilewriter.h"
#include "qgsvectordataprovider.h" #include "qgsvectordataprovider.h"
#include "qgsdistancearea.h" #include "qgsdistancearea.h"
#include <QProgressDialog>






Expand Down Expand Up @@ -607,3 +608,157 @@ QList<QgsPoint> QgsGeometryAnalyzer::extractPoints( QgsGeometry* geometry )
return pointList; 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 );
}
}
}
73 changes: 46 additions & 27 deletions src/analysis/vector/qgsgeometryanalyzer.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
#include "qgsfield.h" #include "qgsfield.h"
#include "qgsdistancearea.h" #include "qgsdistancearea.h"


class QgsVectorFileWriter;
class QProgressDialog;



/** \ingroup analysis /** \ingroup analysis
* The QGis class provides vector geometry analysis functions * The QGis class provides vector geometry analysis functions
Expand All @@ -35,73 +38,86 @@ class ANALYSIS_EXPORT QgsGeometryAnalyzer
{ {
public: public:


/** /**
* Convert a vector layer from single part geometry * Convert a vector layer from single part geometry
* to multipart geometry for a given field * to multipart geometry for a given field
* *
* */ * */
bool singlepartsToMultipart( QgsVectorLayer* layer, bool singlepartsToMultipart( QgsVectorLayer* layer,
const QString& shapefileName, const QString& shapefileName,
const QString& fileEncoding, const QString& fileEncoding,
const int fieldIndex ); const int fieldIndex );


/** /**
* Convert multipart features to multiple singlepart features. Creates * Convert multipart features to multiple singlepart features. Creates
* simple polygons and lines. * simple polygons and lines.
*/ */
bool multipartToSingleparts( QgsVectorLayer* layer, bool multipartToSingleparts( QgsVectorLayer* layer,
const QString& shapefileName, const QString& shapefileName,
const QString& fileEncoding ); const QString& fileEncoding );


/** /**
* Extract nodes from line and polygon vector layers and output them as * Extract nodes from line and polygon vector layers and output them as
* points. * points.
* */ * */
bool extractNodes( QgsVectorLayer* layer, bool extractNodes( QgsVectorLayer* layer,
const QString& shapefileName, const QString& shapefileName,
const QString& fileEncoding ); const QString& fileEncoding );


/** /**
* Convert polygon features to line features. Multipart polygons are * Convert polygon features to line features. Multipart polygons are
* converted to multiple singlepart lines. * converted to multiple singlepart lines.
*/ */
bool polygonsToLines( QgsVectorLayer* layer, bool polygonsToLines( QgsVectorLayer* layer,
const QString& shapefileName, const QString& shapefileName,
const QString& fileEncoding ); const QString& fileEncoding );

/** /**
* Add vector layer geometry info to point (XCOORD, YCOORD), line (LENGTH), * Add vector layer geometry info to point (XCOORD, YCOORD), line (LENGTH),
* or polygon (AREA, PERIMETER) layer. * or polygon (AREA, PERIMETER) layer.
*/ */
bool exportGeometryInformation( QgsVectorLayer* layer, bool exportGeometryInformation( QgsVectorLayer* layer,
const QString& shapefileName, const QString& shapefileName,
const QString& fileEncoding ); const QString& fileEncoding );

/** /**
* Simplify (generalise) line or polygon vector layers using (a modified) * Simplify (generalise) line or polygon vector layers using (a modified)
* Douglas-Peucker algorithm. * Douglas-Peucker algorithm.
*/ */
bool simplifyGeometry( QgsVectorLayer* layer, bool simplifyGeometry( QgsVectorLayer* layer,
const QString shapefileName, const QString shapefileName,
const QString fileEncoding, const QString fileEncoding,
const double tolerance ); const double tolerance );


/** /**
* Calculate the true centroids, or 'center of mass' for each polygon in an * Calculate the true centroids, or 'center of mass' for each polygon in an
* input polygon layer. * input polygon layer.
*/ */
bool polygonCentroids( QgsVectorLayer* layer, bool polygonCentroids( QgsVectorLayer* layer,
const QString& shapefileName, const QString& shapefileName,
const QString& fileEncoding ); 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. * selected features if applicable) and write it out to a shp.
*/ */
bool layerExtent( QgsVectorLayer* layer, bool layerExtent( QgsVectorLayer* layer,
const QString& shapefileName, const QString& shapefileName,
const QString& fileEncoding ); 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: private:


QList<double> simpleMeasure( QgsGeometry* geometry ); QList<double> simpleMeasure( QgsGeometry* geometry );
Expand All @@ -112,6 +128,9 @@ class ANALYSIS_EXPORT QgsGeometryAnalyzer
QgsGeometry* extractAsMulti( QgsGeometry* geometry ); QgsGeometry* extractAsMulti( QgsGeometry* geometry );
QgsGeometry* convertGeometry( QgsGeometry* geometry ); QgsGeometry* convertGeometry( QgsGeometry* geometry );
QList<QgsPoint> extractPoints( 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 #endif //QGSVECTORANALYZER

0 comments on commit 2967013

Please sign in to comment.