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
  • Loading branch information
wonder-sk authored and nyalldawson committed Jan 6, 2021
1 parent a39e162 commit 5454d222e7fdb750529a403e319db23bd4b16187
Showing with 11 additions and 2 deletions.
  1. +11 −2 src/core/vector/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 5454d22

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