mirror of
https://github.com/qgis/QGIS.git
synced 2025-03-01 00:46:20 -05:00
Fix #11965 - improve performance of selectedFeatures()
The slowness of merge / split features tools was caused by the change in the logic in selectedFeatures(): instead of fetching individual features one by one by ID, the whole layer is traversed. Such approach makes sense when many features are selected, but with few features there is considerable delay when dealing with big layers. The implementation is not ideal, but for some common cases the performance is much better. Merging of features now does not request selected features when not necessary. When rendering, avoid using layer's extent() method that may force expensive calculation of layer's extent.
This commit is contained in:
parent
ffd7f8a85d
commit
255cbd2c2a
@ -5911,6 +5911,7 @@ void QgisApp::mergeSelectedFeatures()
|
||||
}
|
||||
|
||||
//get initial selection (may be altered by attribute merge dialog later)
|
||||
QgsFeatureIds featureIds = vl->selectedFeaturesIds();
|
||||
QgsFeatureList featureList = vl->selectedFeatures(); //get QList<QgsFeature>
|
||||
bool canceled;
|
||||
QgsGeometry* unionGeom = unionGeometries( vl, featureList, canceled );
|
||||
@ -5939,9 +5940,9 @@ void QgisApp::mergeSelectedFeatures()
|
||||
return;
|
||||
}
|
||||
|
||||
QgsFeatureList featureListAfter = vl->selectedFeatures();
|
||||
QgsFeatureIds featureIdsAfter = vl->selectedFeaturesIds();
|
||||
|
||||
if ( featureListAfter.size() < 2 )
|
||||
if ( featureIdsAfter.size() < 2 )
|
||||
{
|
||||
QMessageBox::information( 0, tr( "Not enough features selected" ), tr( "The merge tool requires at least two selected features" ) );
|
||||
delete unionGeom;
|
||||
@ -5949,10 +5950,11 @@ void QgisApp::mergeSelectedFeatures()
|
||||
}
|
||||
|
||||
//if the user changed the feature selection in the merge dialog, we need to repeat the union and check the type
|
||||
if ( featureList.size() != featureListAfter.size() )
|
||||
if ( featureIds.size() != featureIdsAfter.size() )
|
||||
{
|
||||
delete unionGeom;
|
||||
bool canceled;
|
||||
QgsFeatureList featureListAfter = vl->selectedFeatures();
|
||||
unionGeom = unionGeometries( vl, featureListAfter, canceled );
|
||||
if ( !unionGeom )
|
||||
{
|
||||
@ -5978,10 +5980,10 @@ void QgisApp::mergeSelectedFeatures()
|
||||
newFeature.setGeometry( unionGeom );
|
||||
newFeature.setAttributes( d.mergedAttributes() );
|
||||
|
||||
QgsFeatureList::const_iterator feature_it = featureListAfter.constBegin();
|
||||
for ( ; feature_it != featureListAfter.constEnd(); ++feature_it )
|
||||
QgsFeatureIds::const_iterator feature_it = featureIdsAfter.constBegin();
|
||||
for ( ; feature_it != featureIdsAfter.constEnd(); ++feature_it )
|
||||
{
|
||||
vl->deleteFeature( feature_it->id() );
|
||||
vl->deleteFeature( *feature_it );
|
||||
}
|
||||
|
||||
vl->addFeature( newFeature, false );
|
||||
|
@ -166,12 +166,11 @@ LayerRenderJobs QgsMapRendererJob::prepareJobs( QPainter* painter, QgsPalLabelin
|
||||
continue;
|
||||
}
|
||||
|
||||
QgsDebugMsg( QString( "layer %1: minscale:%2 maxscale:%3 scaledepvis:%4 extent:%5 blendmode:%6" )
|
||||
QgsDebugMsg( QString( "layer %1: minscale:%2 maxscale:%3 scaledepvis:%4 blendmode:%5" )
|
||||
.arg( ml->name() )
|
||||
.arg( ml->minimumScale() )
|
||||
.arg( ml->maximumScale() )
|
||||
.arg( ml->hasScaleBasedVisibility() )
|
||||
.arg( ml->extent().toString() )
|
||||
.arg( ml->blendMode() )
|
||||
);
|
||||
|
||||
|
@ -2327,13 +2327,26 @@ const QgsFeatureIds& QgsVectorLayer::selectedFeaturesIds() const
|
||||
QgsFeatureList QgsVectorLayer::selectedFeatures()
|
||||
{
|
||||
QgsFeatureList features;
|
||||
|
||||
QgsFeatureIterator it = selectedFeaturesIterator();
|
||||
|
||||
QgsFeature f;
|
||||
while ( it.nextFeature( f ) )
|
||||
|
||||
if ( mSelectedFeatureIds.count() <= 8 )
|
||||
{
|
||||
features.push_back( f );
|
||||
// for small amount of selected features, fetch them directly
|
||||
// because request with FilterFids would go iterate over the whole layer
|
||||
foreach ( int fid, mSelectedFeatureIds )
|
||||
{
|
||||
getFeatures( QgsFeatureRequest( fid ) ).nextFeature( f );
|
||||
features << f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsFeatureIterator it = selectedFeaturesIterator();
|
||||
|
||||
while ( it.nextFeature( f ) )
|
||||
{
|
||||
features.push_back( f );
|
||||
}
|
||||
}
|
||||
|
||||
return features;
|
||||
@ -2341,10 +2354,16 @@ QgsFeatureList QgsVectorLayer::selectedFeatures()
|
||||
|
||||
QgsFeatureIterator QgsVectorLayer::selectedFeaturesIterator( QgsFeatureRequest request )
|
||||
{
|
||||
if ( mSelectedFeatureIds.count() == 0 )
|
||||
return QgsFeatureIterator();
|
||||
|
||||
if ( geometryType() == QGis::NoGeometry )
|
||||
request.setFlags( QgsFeatureRequest::NoGeometry );
|
||||
|
||||
request.setFilterFids( mSelectedFeatureIds );
|
||||
if ( mSelectedFeatureIds.count() == 1 )
|
||||
request.setFilterFid( *mSelectedFeatureIds.constBegin() );
|
||||
else
|
||||
request.setFilterFids( mSelectedFeatureIds );
|
||||
|
||||
return getFeatures( request );
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user