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 fieldsA = dpA->fields(); QgsFieldMap fieldsB = dpB->fields(); combineFieldLists( fieldsA, fieldsB ); QgsVectorFileWriter vWriter( shapefileName, dpA->encoding(), fieldsA, outputType, &crs ); QgsFeature currentFeature; 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() ); } QgsFeature currentFeature; 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 ( layerB->nextFeature( currentFeature ) ) { index.insertFeature( currentFeature ); } QgsFeature 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; }
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; } QgsWkbTypes::Type outputType = dpA->wkbType(); QgsCoordinateReferenceSystem crs = layerA->crs(); QgsFields fieldsA = layerA->fields(); QgsFields fieldsB = layerB->fields(); combineFieldLists( fieldsA, fieldsB ); QgsVectorFileWriter vWriter( shapefileName, dpA->encoding(), fieldsA, outputType, crs ); QgsFeature currentFeature; //take only selection if ( onlySelectedFeatures ) { QgsFeatureIds selectionB = layerB->selectedFeatureIds(); QgsFeatureRequest req = QgsFeatureRequest().setFilterFids( selectionB ).setSubsetOfAttributes( QgsAttributeList() ); QgsSpatialIndex index = QgsSpatialIndex( layerB->getFeatures( req ) ); //use QgsVectorLayer::featureAtId const QgsFeatureIds selectionA = layerA->selectedFeatureIds(); if ( p ) { p->setMaximum( selectionA.size() ); } req = QgsFeatureRequest().setFilterFids( selectionA ); QgsFeatureIterator selectionAIt = layerA->getFeatures( req ); QgsFeature currentFeature; int processedFeatures = 0; while ( selectionAIt.nextFeature( currentFeature ) ) { if ( p ) { p->setValue( processedFeatures ); } if ( p && p->wasCanceled() ) { break; } intersectFeature( currentFeature, &vWriter, layerB, &index ); ++processedFeatures; } if ( p ) { p->setValue( selectionA.size() ); } } //take all features else { QgsFeatureRequest req = QgsFeatureRequest().setSubsetOfAttributes( QgsAttributeList() ); QgsSpatialIndex index = QgsSpatialIndex( layerB->getFeatures( req ) ); int featureCount = layerA->featureCount(); if ( p ) { p->setMaximum( featureCount ); } int processedFeatures = 0; QgsFeatureIterator fit = layerA->getFeatures(); QgsFeature currentFeature; while ( fit.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; }