Skip to content
Permalink
Browse files

Split tool: create new features all at once (fixes #40860)

The cause of the slowness of split tool on layers with many features
(e.g. more than 100k) was due to lots of QgsVectorLayer::uniqueValues()
calls when creating features. If we create the new features all at once,
the returned unique values get calculated just once and cached,
which makes things much faster.

Results on testing datasets:
- ~130k polygons: before ~6s, after ~0.5s
- ~1M lines: before ~100+s, after ~3s

(cherry picked from commit 5454d22)
  • Loading branch information
wonder-sk authored and nyalldawson committed Jan 6, 2021
1 parent b75b875 commit d73fd7c1a79122370040fcf985d8cf3f5334d499
Showing with 11 additions and 2 deletions.
  1. +11 −2 src/core/qgsvectorlayereditutils.cpp
@@ -356,6 +356,8 @@ QgsGeometry::OperationResult QgsVectorLayerEditUtils::splitFeatures( const QgsCu
features = mLayer->getFeatures( QgsFeatureRequest().setFilterRect( bBox ).setFlags( QgsFeatureRequest::ExactIntersect ) );
}

QgsVectorLayerUtils::QgsFeaturesDataList featuresDataToAdd;

QgsFeature feat;
while ( features.nextFeature( feat ) )
{
@@ -377,8 +379,7 @@ QgsGeometry::OperationResult QgsVectorLayerEditUtils::splitFeatures( const QgsCu
QgsAttributeMap attributeMap = feat.attributes().toMap();
for ( const QgsGeometry &geom : qgis::as_const( newGeometries ) )
{
QgsFeature f = QgsVectorLayerUtils::createFeature( mLayer, geom, attributeMap );
mLayer->addFeature( f );
featuresDataToAdd << QgsVectorLayerUtils::QgsFeatureData( geom, attributeMap );
}

if ( topologicalEditing )
@@ -397,6 +398,14 @@ QgsGeometry::OperationResult QgsVectorLayerEditUtils::splitFeatures( const QgsCu
}
}

if ( !featuresDataToAdd.isEmpty() )
{
// finally create and add all bits of geometries cut off the original geometries
// (this is much faster than creating features one by one)
QgsFeatureList featuresListToAdd = QgsVectorLayerUtils::createFeatures( mLayer, featuresDataToAdd );
mLayer->addFeatures( featuresListToAdd );
}

if ( numberOfSplitFeatures == 0 )
{
returnCode = QgsGeometry::OperationResult::NothingHappened;

0 comments on commit d73fd7c

Please sign in to comment.
You can’t perform that action at this time.