Skip to content
Permalink
Browse files

Merge pull request #9203 from elpaso/bugfix-21305-paste-slow-no-provider

Cache unique values when creating features
  • Loading branch information
elpaso committed Feb 21, 2019
2 parents 4d5dad8 + 4250ef2 commit 17280c3e4df4313900a246e4e049b42fd4e06854
@@ -57,6 +57,40 @@ Returns the duplicated features in the given layer

};

class QgsFeatureData
{
%Docstring
Encapsulate geometry and attributes for new features, to be passed to createFeatures

.. seealso:: :py:func:`createFeatures`

.. versionadded:: 3.6
%End

%TypeHeaderCode
#include "qgsvectorlayerutils.h"
%End
public:

QgsFeatureData( const QgsGeometry &geometry = QgsGeometry(), const QgsAttributeMap &attributes = QgsAttributeMap() );
%Docstring
Constructs a new QgsFeatureData with given ``geometry`` and ``attributes``
%End

QgsGeometry geometry() const;
%Docstring
Returns geometry
%End

QgsAttributeMap attributes() const;
%Docstring
Returns attributes
%End

};

typedef QList<QgsVectorLayerUtils::QgsFeatureData> QgsFeaturesDataList;

static QgsFeatureIterator getValuesIterator( const QgsVectorLayer *layer, const QString &fieldOrExpression, bool &ok, bool selectedOnly );
%Docstring
Create a feature iterator for a specified field name or expression.
@@ -122,6 +156,15 @@ Returns a new attribute value for the specified field index which is guaranteed
value can be used as a basis for generated values.

.. seealso:: :py:func:`valueExists`
%End

static QVariant createUniqueValueFromCache( const QgsVectorLayer *layer, int fieldIndex, const QSet<QVariant> &existingValues, const QVariant &seed = QVariant() );
%Docstring
Returns a new attribute value for the specified field index which is guaranteed to
be unique within regard to ``existingValues``.
The optional seed value can be used as a basis for generated values.

.. versionadded:: 3.6
%End

static bool validateAttribute( const QgsVectorLayer *layer, const QgsFeature &feature, int attributeIndex, QStringList &errors /Out/,
@@ -143,6 +186,21 @@ Creates a new feature ready for insertion into a layer. Default values and const
passed for the new feature to copy as many attribute values as possible from the map,
assuming that they respect the layer's constraints. Note that the created feature is not
automatically inserted into the layer.

.. seealso:: :py:func:`createFeatures`
%End

static QgsFeatureList createFeatures( const QgsVectorLayer *layer,
const QgsFeaturesDataList &featuresData,
QgsExpressionContext *context = 0 );
%Docstring
Creates a set of new features ready for insertion into a layer. Default values and constraints
(e.g., unique constraints) will automatically be handled. Note that the created features are not
automatically inserted into the layer.

.. seealso:: :py:func:`createFeature`

.. versionadded:: 3.6
%End

static QgsFeature duplicateFeature( QgsVectorLayer *layer, const QgsFeature &feature, QgsProject *project, int depth, QgsDuplicateFeatureContext &duplicateFeatureContext /Out/ );
@@ -8996,11 +8996,12 @@ void QgisApp::pasteFromClipboard( QgsMapLayer *destinationLayer )
QgsExpressionContext context = pasteVectorLayer->createExpressionContext();

QgsFeatureList compatibleFeatures( QgsVectorLayerUtils::makeFeaturesCompatible( features, pasteVectorLayer ) );
QgsFeatureList newFeatures;
QgsVectorLayerUtils::QgsFeaturesDataList newFeaturesDataList;
newFeaturesDataList.reserve( compatibleFeatures.size() );

// Count collapsed geometries
int invalidGeometriesCount = 0;

newFeatures.reserve( compatibleFeatures.size() );
for ( const auto &feature : qgis::as_const( compatibleFeatures ) )
{

@@ -9020,10 +9021,12 @@ void QgisApp::pasteFromClipboard( QgsMapLayer *destinationLayer )
{
attrMap[i] = feature.attribute( i );
}
// now create new feature using pasted feature as a template. This automatically handles default
// values and field constraints
newFeatures << QgsVectorLayerUtils::createFeature( pasteVectorLayer, geom, attrMap, &context );
newFeaturesDataList << QgsVectorLayerUtils::QgsFeatureData( geom, attrMap );
}

// now create new feature using pasted feature as a template. This automatically handles default
// values and field constraints
QgsFeatureList newFeatures {QgsVectorLayerUtils::createFeatures( pasteVectorLayer, newFeaturesDataList, &context )};
pasteVectorLayer->addFeatures( newFeatures );
QgsFeatureIds newIds;
newIds.reserve( newFeatures.size() );
@@ -9032,7 +9035,6 @@ void QgisApp::pasteFromClipboard( QgsMapLayer *destinationLayer )
newIds << f.id();
}


pasteVectorLayer->selectByIds( newIds );
pasteVectorLayer->endEditCommand();
pasteVectorLayer->updateExtents();
@@ -277,7 +277,7 @@ void QgsAttributesFormProperties::loadAttributeTypeDialog()

void QgsAttributesFormProperties::storeAttributeTypeDialog()
{
if ( mAttributeTypeDialog->fieldIdx() < 0 )
if ( mAttributeTypeDialog->fieldIdx() < 0 || mAttributeTypeDialog->fieldIdx() >= mLayer->fields().count() )
return;

FieldConfig cfg;

0 comments on commit 17280c3

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