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/qgis@11623 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
mhugent committed Sep 11, 2009
1 parent 968cad9 commit b2249cc
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
Expand Up @@ -97,7 +97,7 @@ INSTALL(TARGETS qgis_analysis

# Added by Tim to install headers

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

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



Expand Down Expand Up @@ -607,3 +608,157 @@ QList<QgsPoint> QgsGeometryAnalyzer::extractPoints( QgsGeometry* geometry )
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
Expand Up @@ -26,6 +26,9 @@
#include "qgsfield.h"
#include "qgsdistancearea.h"

class QgsVectorFileWriter;
class QProgressDialog;


/** \ingroup analysis
* The QGis class provides vector geometry analysis functions
Expand All @@ -35,73 +38,86 @@ class ANALYSIS_EXPORT QgsGeometryAnalyzer
{
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 );
Expand All @@ -112,6 +128,9 @@ class ANALYSIS_EXPORT QgsGeometryAnalyzer
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

0 comments on commit b2249cc

Please sign in to comment.