From c1b360bd936737406b8f70dd4bc438a0a2fc2655 Mon Sep 17 00:00:00 2001 From: cfarmer Date: Sun, 8 Nov 2009 23:10:48 +0000 Subject: [PATCH] Fix crashes due to geometry pointers in QgsGeometryAnalyzer; Add QgsOverlayAnalyzer to analysis library (currently only supports intersections) git-svn-id: http://svn.osgeo.org/qgis/trunk@12040 c8812cc2-4d05-0410-92ff-de0c093fc19c --- python/analysis/analysis.sip | 1 + src/analysis/CMakeLists.txt | 4 +- src/analysis/vector/qgsgeometryanalyzer.cpp | 191 ++++++++++++------ src/analysis/vector/qgsoverlayanalyzer.cpp | 204 ++++++++++++++++++++ src/analysis/vector/qgsoverlayanalyzer.h | 105 ++++++++++ 5 files changed, 449 insertions(+), 56 deletions(-) create mode 100644 src/analysis/vector/qgsoverlayanalyzer.cpp create mode 100644 src/analysis/vector/qgsoverlayanalyzer.h diff --git a/python/analysis/analysis.sip b/python/analysis/analysis.sip index c4594a60d99..d7f0f08b20b 100644 --- a/python/analysis/analysis.sip +++ b/python/analysis/analysis.sip @@ -8,4 +8,5 @@ %Import core/core.sip %Include qgsgeometryanalyzer.sip +%Include qgsoverlayanalyzer.sip diff --git a/src/analysis/CMakeLists.txt b/src/analysis/CMakeLists.txt index 39be01d3084..1189541b279 100644 --- a/src/analysis/CMakeLists.txt +++ b/src/analysis/CMakeLists.txt @@ -31,6 +31,7 @@ SET(QGIS_ANALYSIS_SRCS raster/qgstotalcurvaturefilter.cpp vector/qgsgeometryanalyzer.cpp vector/qgszonalstatistics.cpp + vector/qgsoverlayanalyzer.cpp ) SET(QGIS_ANALYSIS_MOC_HDRS @@ -43,6 +44,7 @@ INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../core/ ${CMAKE_CURRENT_SOURCE_DIR}/../core/renderer + ${CMAKE_CURRENT_SOURCE_DIR}/../core/spatialindex interpolation ${PROJ_INCLUDE_DIR} ${GEOS_INCLUDE_DIR} @@ -99,7 +101,7 @@ INSTALL(TARGETS qgis_analysis # Added by Tim to install headers -SET(QGIS_ANALYSIS_HDRS vector/qgsgeometryanalyzer.h vector/qgszonalstatistics.h +SET(QGIS_ANALYSIS_HDRS vector/qgsgeometryanalyzer.h vector/qgszonalstatistics.h vector/qgsgeometryanalyzer.h ) INSTALL(CODE "MESSAGE(\"Installing ANALYSIS headers...\")") diff --git a/src/analysis/vector/qgsgeometryanalyzer.cpp b/src/analysis/vector/qgsgeometryanalyzer.cpp index 761723f3794..ca2c9619056 100644 --- a/src/analysis/vector/qgsgeometryanalyzer.cpp +++ b/src/analysis/vector/qgsgeometryanalyzer.cpp @@ -329,6 +329,7 @@ bool QgsGeometryAnalyzer::extent( QgsVectorLayer* layer, const QString& shapefil QList QgsGeometryAnalyzer::simpleMeasure( QgsGeometry* mpGeometry ) { QList list; + double perim; if ( mpGeometry->wkbType() == QGis::WKBPoint ) { QgsPoint pt = mpGeometry->asPoint(); @@ -341,11 +342,11 @@ QList QgsGeometryAnalyzer::simpleMeasure( QgsGeometry* mpGeometry ) list.append( measure.measure( mpGeometry ) ); if ( mpGeometry->type() == QGis::Polygon ) { - list.append( perimeterMeasure( mpGeometry, measure ) ); + perim = perimeterMeasure( mpGeometry, measure ); + list.append( perim ); } } return list; - } double QgsGeometryAnalyzer::perimeterMeasure( QgsGeometry* geometry, QgsDistanceArea& measure ) @@ -383,22 +384,12 @@ bool QgsGeometryAnalyzer::convexHull( QgsVectorLayer* layer, const QString& shap { return false; } - QgsVectorDataProvider* dp = layer->dataProvider(); if ( !dp ) { return false; } - - QGis::WkbType outputType = QGis::WKBPolygon; - const QgsCoordinateReferenceSystem crs = layer->srs(); - - QgsVectorFileWriter vWriter( shapefileName, dp->encoding(), dp->fields(), outputType, &crs ); - QgsFeature currentFeature; - QgsGeometry* dissolveGeometry; //dissolve geometry - QMultiMap map; bool useField = false; - if ( uniqueIdField == -1 ) { uniqueIdField = 0; @@ -406,14 +397,63 @@ bool QgsGeometryAnalyzer::convexHull( QgsVectorLayer* layer, const QString& shap else { useField = true; + } + QgsFieldMap fields; + fields.insert( 0 , QgsField( QString( "UID" ), QVariant::String ) ); + fields.insert( 1 , QgsField( QString( "AREA" ), QVariant::Double ) ); + fields.insert( 2 , QgsField( QString( "PERIM" ), QVariant::Double ) ); + + QGis::WkbType outputType = QGis::WKBPolygon; + const QgsCoordinateReferenceSystem crs = layer->srs(); + + QgsVectorFileWriter vWriter( shapefileName, dp->encoding(), fields, outputType, &crs ); + QgsFeature currentFeature; + QgsGeometry* dissolveGeometry; //dissolve geometry + QMultiMap map; + + if ( onlySelectedFeatures ) + { + //use QgsVectorLayer::featureAtId + const QgsFeatureIds selection = layer->selectedFeaturesIds(); + QgsFeatureIds::const_iterator it = selection.constBegin(); + for ( ; it != selection.constEnd(); ++it ) + { +// if ( p ) +// { +// p->setValue( processedFeatures ); +// } +// if ( p && p->wasCanceled() ) +// { +// // break; // it may be better to do something else here? +// return false; +// } + if ( !layer->featureAtId( *it, currentFeature, true, true ) ) + { + continue; + } + map.insert( currentFeature.attributeMap()[ uniqueIdField ].toString(), currentFeature.id() ); + } + } + else + { layer->select( layer->pendingAllAttributesList(), QgsRectangle(), true, false ); while ( layer->nextFeature( currentFeature ) ) { - map.insert( currentFeature.attributeMap()[uniqueIdField].toString(), currentFeature.id() ); + // if ( p ) + // { + // p->setValue( processedFeatures ); + // } + // if ( p && p->wasCanceled() ) + // { + // // break; // it may be better to do something else here? + // return false; + // } + map.insert( currentFeature.attributeMap()[ uniqueIdField ].toString(), currentFeature.id() ); } } - QMultiMap::const_iterator jt; - for (jt = map.constBegin(); jt != map.constEnd(); ++jt) + + QMultiMap::const_iterator jt = map.constBegin(); + while ( jt != map.constEnd() ) { QString currentKey = jt.key(); int processedFeatures = 0; @@ -421,13 +461,13 @@ bool QgsGeometryAnalyzer::convexHull( QgsVectorLayer* layer, const QString& shap if ( onlySelectedFeatures ) { //use QgsVectorLayer::featureAtId - const QgsFeatureIds selection = layer->selectedFeaturesIds(); + const QgsFeatureIds selection = layer->selectedFeaturesIds(); if ( p ) { - p->setMaximum( selection.size() ); + p->setMaximum( selection.size() ); } processedFeatures = 0; - while ( jt != map.end() && ( jt.key() == currentKey || !useField ) ) + while ( jt != map.constEnd() && ( jt.key() == currentKey || !useField ) ) { if ( p && p->wasCanceled() ) { @@ -437,18 +477,26 @@ bool QgsGeometryAnalyzer::convexHull( QgsVectorLayer* layer, const QString& shap { if ( p ) { - p->setValue( processedFeatures ); + p->setValue( processedFeatures ); } if ( !layer->featureAtId( jt.value(), currentFeature, true, true ) ) { - continue; + continue; } convexFeature( currentFeature, processedFeatures, &dissolveGeometry ); ++processedFeatures; } ++jt; } + QList values; + dissolveGeometry = dissolveGeometry->convexHull(); + values = simpleMeasure( dissolveGeometry ); + QgsAttributeMap attributeMap; + attributeMap.insert( 0 , QVariant( currentKey ) ); + attributeMap.insert( 1 , values[ 0 ] ); + attributeMap.insert( 2 , values[ 1 ] ); QgsFeature dissolveFeature; + dissolveFeature.setAttributeMap( attributeMap ); dissolveFeature.setGeometry( dissolveGeometry ); vWriter.addFeature( dissolveFeature ); } @@ -461,7 +509,7 @@ bool QgsGeometryAnalyzer::convexHull( QgsVectorLayer* layer, const QString& shap p->setMaximum( featureCount ); } processedFeatures = 0; - while ( jt != map.end() && ( jt.key() == currentKey || !useField ) ) + while ( jt != map.constEnd() && ( jt.key() == currentKey || !useField ) ) { if ( p ) { @@ -480,9 +528,19 @@ bool QgsGeometryAnalyzer::convexHull( QgsVectorLayer* layer, const QString& shap ++processedFeatures; ++jt; } - QgsFeature dissolveFeature; - dissolveFeature.setGeometry( dissolveGeometry ); - vWriter.addFeature( dissolveFeature ); + QList values; + // QgsGeometry* tmpGeometry = 0; + dissolveGeometry = dissolveGeometry->convexHull(); + // values = simpleMeasure( tmpGeometry ); + values = simpleMeasure( dissolveGeometry ); + QgsAttributeMap attributeMap; + attributeMap.insert( 0 , QVariant( currentKey ) ); + attributeMap.insert( 1 , QVariant( values[ 0 ] ) ); + attributeMap.insert( 2 , QVariant( values[ 1 ] ) ); + QgsFeature dissolveFeature; + dissolveFeature.setAttributeMap( attributeMap ); + dissolveFeature.setGeometry( dissolveGeometry ); + vWriter.addFeature( dissolveFeature ); } } return true; @@ -522,22 +580,12 @@ bool QgsGeometryAnalyzer::dissolve( QgsVectorLayer* layer, const QString& shapef { return false; } - QgsVectorDataProvider* dp = layer->dataProvider(); if ( !dp ) { return false; } - - QGis::WkbType outputType = dp->geometryType(); - const QgsCoordinateReferenceSystem crs = layer->srs(); - - QgsVectorFileWriter vWriter( shapefileName, dp->encoding(), dp->fields(), outputType, &crs ); - QgsFeature currentFeature; - QgsGeometry* dissolveGeometry; //dissolve geometry - QMultiMap map; bool useField = false; - if ( uniqueIdField == -1 ) { uniqueIdField = 0; @@ -545,28 +593,56 @@ bool QgsGeometryAnalyzer::dissolve( QgsVectorLayer* layer, const QString& shapef else { useField = true; + } + + QGis::WkbType outputType = dp->geometryType(); + const QgsCoordinateReferenceSystem crs = layer->srs(); + + QgsVectorFileWriter vWriter( shapefileName, dp->encoding(), dp->fields(), outputType, &crs ); + QgsFeature currentFeature; + QMultiMap map; + + if ( onlySelectedFeatures ) + { + //use QgsVectorLayer::featureAtId + const QgsFeatureIds selection = layer->selectedFeaturesIds(); + QgsFeatureIds::const_iterator it = selection.constBegin(); + for ( ; it != selection.constEnd(); ++it ) + { + if ( !layer->featureAtId( *it, currentFeature, true, true ) ) + { + continue; + } + map.insert( currentFeature.attributeMap()[ uniqueIdField ].toString(), currentFeature.id() ); + } + } + else + { layer->select( layer->pendingAllAttributesList(), QgsRectangle(), true, false ); while ( layer->nextFeature( currentFeature ) ) { - map.insert( currentFeature.attributeMap()[uniqueIdField].toString(), currentFeature.id() ); + map.insert( currentFeature.attributeMap()[ uniqueIdField ].toString(), currentFeature.id() ); } } - QMultiMap::const_iterator jt; - for (jt = map.constBegin(); jt != map.constEnd(); ++jt) + + QgsGeometry* dissolveGeometry; //dissolve geometry + QMultiMap::const_iterator jt = map.constBegin(); + QgsFeature outputFeature; + while ( jt != map.constEnd() ) { QString currentKey = jt.key(); int processedFeatures = 0; + bool first = true; //take only selection if ( onlySelectedFeatures ) { //use QgsVectorLayer::featureAtId - const QgsFeatureIds selection = layer->selectedFeaturesIds(); + const QgsFeatureIds selection = layer->selectedFeaturesIds(); if ( p ) { - p->setMaximum( selection.size() ); + p->setMaximum( selection.size() ); } - processedFeatures = 0; - while ( jt != map.end() && ( jt.key() == currentKey || !useField ) ) + while ( jt != map.constEnd() && ( jt.key() == currentKey || !useField ) ) { if ( p && p->wasCanceled() ) { @@ -576,20 +652,22 @@ bool QgsGeometryAnalyzer::dissolve( QgsVectorLayer* layer, const QString& shapef { if ( p ) { - p->setValue( processedFeatures ); + p->setValue( processedFeatures ); } if ( !layer->featureAtId( jt.value(), currentFeature, true, true ) ) { - continue; + continue; + } + if ( first ) + { + outputFeature.setAttributeMap( currentFeature.attributeMap() ); + first = false; } dissolveFeature( currentFeature, processedFeatures, &dissolveGeometry ); ++processedFeatures; } ++jt; } - QgsFeature dissolveFeature; - dissolveFeature.setGeometry( dissolveGeometry ); - vWriter.addFeature( dissolveFeature ); } //take all features else @@ -599,8 +677,7 @@ bool QgsGeometryAnalyzer::dissolve( QgsVectorLayer* layer, const QString& shapef { p->setMaximum( featureCount ); } - processedFeatures = 0; - while ( jt != map.end() && ( jt.key() == currentKey || !useField ) ) + while ( jt != map.constEnd() && ( jt.key() == currentKey || !useField ) ) { if ( p ) { @@ -615,14 +692,17 @@ bool QgsGeometryAnalyzer::dissolve( QgsVectorLayer* layer, const QString& shapef { continue; } + { + outputFeature.setAttributeMap( currentFeature.attributeMap() ); + first = false; + } dissolveFeature( currentFeature, processedFeatures, &dissolveGeometry ); ++processedFeatures; ++jt; } - QgsFeature dissolveFeature; - dissolveFeature.setGeometry( dissolveGeometry ); - vWriter.addFeature( dissolveFeature ); } + outputFeature.setGeometry( dissolveGeometry ); + vWriter.addFeature( outputFeature ); } return true; } @@ -630,7 +710,6 @@ bool QgsGeometryAnalyzer::dissolve( QgsVectorLayer* layer, const QString& shapef void QgsGeometryAnalyzer::dissolveFeature( QgsFeature& f, int nProcessedFeatures, QgsGeometry** dissolveGeometry ) { QgsGeometry* featureGeometry = f.geometry(); - QgsGeometry* tmpGeometry = 0; if ( !featureGeometry ) { @@ -639,13 +718,15 @@ void QgsGeometryAnalyzer::dissolveFeature( QgsFeature& f, int nProcessedFeatures if ( nProcessedFeatures == 0 ) { - *dissolveGeometry = featureGeometry; + int geomSize = featureGeometry->wkbSize(); + *dissolveGeometry = new QgsGeometry(); + unsigned char* wkb = new unsigned char[geomSize]; + memcpy(wkb, featureGeometry->asWkb(), geomSize); + (*dissolveGeometry)->fromWkb(wkb, geomSize); } else { - tmpGeometry = *dissolveGeometry; *dissolveGeometry = ( *dissolveGeometry )->combine( featureGeometry ); - delete tmpGeometry; } } diff --git a/src/analysis/vector/qgsoverlayanalyzer.cpp b/src/analysis/vector/qgsoverlayanalyzer.cpp new file mode 100644 index 00000000000..b20dc48ba85 --- /dev/null +++ b/src/analysis/vector/qgsoverlayanalyzer.cpp @@ -0,0 +1,204 @@ +/*************************************************************************** + qgsoverlayanalyzer.cpp - QGIS Tools for vector geometry analysis + ------------------- + begin : 8 Nov 2009 + copyright : (C) Carson J. Q. Farmer + email : carson.farmer@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +/* $Id: qgis.h 9774 2008-12-12 05:41:24Z timlinux $ */ + +#include "qgsoverlayanalyzer.h" + +#include "qgsapplication.h" +#include "qgsfield.h" +#include "qgsfeature.h" +#include "qgslogger.h" +#include "qgscoordinatereferencesystem.h" +#include "qgsvectorfilewriter.h" +#include "qgsvectordataprovider.h" +#include "qgsdistancearea.h" +#include + +bool QgsOverlayAnalyzer::intersection( QgsVectorLayer* layerA, QgsVectorLayer* layerB, + const QString& shapefileName, bool onlySelectedFeatures, + QProgressDialog* p ) +{ + if ( !layerA && !layerB ) + { + return false; + } + + QgsVectorDataProvider* dpA = layerA->dataProvider(); + QgsVectorDataProvider* dpB = layerB->dataProvider(); + if ( !dpA && !dpB ) + { + return false; + } + + QGis::WkbType outputType = dpA->geometryType(); + const QgsCoordinateReferenceSystem crs = layerA->srs(); + QgsFieldMap fields; + //fields = combineFieldLists( dpA->fields(), dpB->fields() ); + + QgsVectorFileWriter vWriter( shapefileName, dpA->encoding(), fields, outputType, &crs ); + QgsFeature currentFeature; + QgsGeometry* dissolveGeometry; //dissolve geometry (if dissolve enabled) + QgsSpatialIndex index; + + //take only selection + if ( onlySelectedFeatures ) + { + const QgsFeatureIds selectionB = layerB->selectedFeaturesIds(); + QgsFeatureIds::const_iterator it = selectionB.constBegin(); + for ( ; it != selectionB.constEnd(); ++it ) + { + if ( !layerB->featureAtId( *it, currentFeature, true, true ) ) + { + continue; + } + index.insertFeature( currentFeature ); + } + //use QgsVectorLayer::featureAtId + const QgsFeatureIds selectionA = layerA->selectedFeaturesIds(); + if ( p ) + { + p->setMaximum( selectionA.size() ); + } + + int processedFeatures = 0; + it = selectionA.constBegin(); + for ( ; it != selectionA.constEnd(); ++it ) + { + if ( p ) + { + p->setValue( processedFeatures ); + } + + if ( p && p->wasCanceled() ) + { + break; + } + if ( !layerA->featureAtId( *it, currentFeature, true, true ) ) + { + continue; + } + intersectFeature( currentFeature, &vWriter, layerB, &index ); + ++processedFeatures; + } + + if ( p ) + { + p->setValue( selectionA.size() ); + } + } + //take all features + else + { + layerB->select( layerB->pendingAllAttributesList(), QgsRectangle(), true, false ); + while ( dpB->nextFeature( currentFeature ) ) + { + index.insertFeature( currentFeature ); + } + + layerA->select( layerA->pendingAllAttributesList(), QgsRectangle(), true, false ); + + int featureCount = layerA->featureCount(); + if ( p ) + { + p->setMaximum( featureCount ); + } + int processedFeatures = 0; + + while ( layerA->nextFeature( currentFeature ) ) + { + if ( p ) + { + p->setValue( processedFeatures ); + } + if ( p && p->wasCanceled() ) + { + break; + } + intersectFeature( currentFeature, &vWriter, layerB, &index ); + ++processedFeatures; + } + if ( p ) + { + p->setValue( featureCount ); + } + } + return true; +} + +void QgsOverlayAnalyzer::intersectFeature( QgsFeature& f, QgsVectorFileWriter* vfw, + QgsVectorLayer* vl, QgsSpatialIndex* index ) +{ + QgsGeometry* featureGeometry = f.geometry(); + QgsGeometry* intersectGeometry = 0; + QgsFeature currentFeature; + + if ( !featureGeometry ) + { + return; + } + + QList intersects; + intersects = index->intersects( featureGeometry->boundingBox() ); + QList::const_iterator it = intersects.constBegin(); + for ( ; it != intersects.constEnd(); ++it ) + { + if ( !vl->featureAtId( *it, currentFeature, true, true ) ) + { + continue; + } + + if ( featureGeometry->intersects( currentFeature.geometry() ) ) + { + intersectGeometry = featureGeometry->intersection( currentFeature.geometry() ); + + QgsFeature outFeature; + outFeature.setGeometry( intersectGeometry ); + outFeature.setAttributeMap( f.attributeMap() ); + + //add it to vector file writer + if ( vfw ) + { + vfw->addFeature( outFeature ); + } + } + } +} + +void QgsOverlayAnalyzer::combineFieldLists( QgsFieldMap fieldListA, QgsFieldMap fieldListB ) +{ + QMap::const_iterator i = fieldListB.constBegin(); + int count = 0; + while ( i != fieldListB.constEnd() ) + { + if ( !fieldListA.contains( i.key() ) ) + { + fieldListA.insert( fieldListA.size()-1, i.value() ); + count = 0; + } + else + { + QgsField field; + field = i.value(); + QString name = field.name(); + name.append( "_" ).append( QString( count ) ); + fieldListA.insert( fieldListA.size()-1 , QgsField( name, field.type() ) ); + ++count; + continue; + } + ++i; + } +} diff --git a/src/analysis/vector/qgsoverlayanalyzer.h b/src/analysis/vector/qgsoverlayanalyzer.h new file mode 100644 index 00000000000..004875b3256 --- /dev/null +++ b/src/analysis/vector/qgsoverlayanalyzer.h @@ -0,0 +1,105 @@ +/*************************************************************************** + qgsoverlayanalyzer.h - QGIS Tools for vector geometry analysis + ------------------- + begin : 19 March 2009 + copyright : (C) Carson Farmer + email : carson.farmer@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +/* $Id: qgis.h 9774 2008-12-12 05:41:24Z timlinux $ */ + +#ifndef QGSOVERLAYANALYZERH +#define QGSOVERLAYANALYZERH + +#include "qgsvectorlayer.h" +#include "qgsfield.h" +#include "qgsspatialindex.h" +#include "qgsfeature.h" +#include "qgsgeometry.h" +#include "qgsfield.h" +#include "qgsdistancearea.h" + +class QgsVectorFileWriter; +class QProgressDialog; + + +/** \ingroup analysis + * The QGis class provides vector overlay analysis functions + */ + +class ANALYSIS_EXPORT QgsOverlayAnalyzer +{ + public: + + /**Perform an intersection on two input vector layers and write output to a new shape file + @param layerA input vector layer + @param layerB input vector layer + @param shapefileName path to the output shp + @param onlySelectedFeatures if true, only selected features are considered, else all the features + @param p progress dialog (or 0 if no progress dialog is to be shown) + @note: added in version 1.4*/ + bool intersection( QgsVectorLayer* layerA, QgsVectorLayer* layerB, \ + const QString& shapefileName, bool onlySelectedFeatures = false, \ + QProgressDialog* p = 0 ); + +// /**Perform a union of two input vector layers and write output to a new shape file +// @param layerA input vector layer +// @param layerB input vector layer +// @param shapefileName path to the output shp +// @param onlySelectedFeatures if true, only selected features are considered, else all the features +// @param p progress dialog (or 0 if no progress dialog is to be shown) +// @note: added in version 1.4*/ +// bool combine( QgsVectorLayer* layerA, QgsVectorLayer* layerB, +// const QString& shapefileName, bool onlySelectedFeatures = false, +// QProgressDialog* p = 0 ); +// +// /**Clip a vector layer based on the boundary of another vector layer and +// write output to a new shape file +// @param layerA input vector layer +// @param layerB input vector layer +// @param shapefileName path to the output shp +// @param onlySelectedFeatures if true, only selected features are considered, else all the features +// @param p progress dialog (or 0 if no progress dialog is to be shown) +// @note: added in version 1.4*/ +// bool clip( QgsVectorLayer* layerA, QgsVectorLayer* layerB, +// const QString& shapefileName, bool onlySelectedFeatures = false, +// QProgressDialog* p = 0 ); +// +// /**Difference a vector layer based on the geometries of another vector layer +// and write the output to a new shape file +// @param layerA input vector layer +// @param layerB input vector layer +// @param shapefileName path to the output shp +// @param onlySelectedFeatures if true, only selected features are considered, else all the features +// @param p progress dialog (or 0 if no progress dialog is to be shown) +// @note: added in version 1.4*/ +// bool difference( QgsVectorLayer* layerA, QgsVectorLayer* layerB, +// const QString& shapefileName, bool onlySelectedFeatures = false, +// QProgressDialog* p = 0 ); +// +// /**Intersect two vector layers and write the geometries of each layer that +// do not intersect with the other layer to a new shape file (Symmetrical difference) +// @param layerA input vector layer +// @param layerB input vector layer +// @param shapefileName path to the output shp +// @param onlySelectedFeatures if true, only selected features are considered, else all the features +// @param p progress dialog (or 0 if no progress dialog is to be shown) +// @note: added in version 1.4*/ +// bool symDifference( QgsVectorLayer* layerA, QgsVectorLayer* layerB, +// const QString& shapefileName, bool onlySelectedFeatures = false, +// QProgressDialog* p = 0 ); + + private: + + void combineFieldLists( QgsFieldMap fieldListA, QgsFieldMap fieldListB ); + void intersectFeature( QgsFeature& f, QgsVectorFileWriter* vfw, QgsVectorLayer* dp, QgsSpatialIndex* index ); +}; +#endif //QGSVECTORANALYZER