Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add method to match feature attributes to the given fields
Refs #18784
  • Loading branch information
nyalldawson committed Sep 24, 2018
1 parent 81487f9 commit a879400
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 0 deletions.
10 changes: 10 additions & 0 deletions python/core/auto_generated/qgsvectorlayerutils.sip.in
Expand Up @@ -156,6 +156,16 @@ The duplicated feature will be automatically inserted into the layer.
.. versionadded:: 3.0
%End


static void matchAttributesToFields( QgsFeature &feature, const QgsFields &fields );
%Docstring
Matches the attributes in ``feature`` to the specified ``fields``.

This causes the attributes contained within the given ``feature`` to be rearranged (or in
some cases dropped) in order to match the fields and order indicated by ``fields``.

.. versionadded:: 3.4
%End
};


Expand Down
38 changes: 38 additions & 0 deletions src/core/qgsvectorlayerutils.cpp
Expand Up @@ -522,6 +522,44 @@ std::unique_ptr<QgsVectorLayerFeatureSource> QgsVectorLayerUtils::getFeatureSour
return featureSource;
}

void QgsVectorLayerUtils::matchAttributesToFields( QgsFeature &feature, const QgsFields &fields )
{
if ( !feature.fields().isEmpty() )
{
QgsAttributes attributes;
attributes.reserve( fields.size() );
// feature has a field mapping, so we can match attributes to field names
for ( const QgsField &field : fields )
{
int index = feature.fields().lookupField( field.name() );
attributes.append( index >= 0 ? feature.attribute( index ) : QVariant( field.type() ) );
}
feature.setAttributes( attributes );
}
else
{
// no field name mapping in feature, just use order
const int lengthDiff = feature.attributes().count() - fields.count();
if ( lengthDiff > 0 )
{
// truncate extra attributes
QgsAttributes attributes = feature.attributes().mid( 0, fields.count() );
feature.setAttributes( attributes );
}
else if ( lengthDiff < 0 )
{
// add missing null attributes
QgsAttributes attributes = feature.attributes();
attributes.reserve( fields.count() );
for ( int i = feature.attributes().count(); i < fields.count(); ++i )
{
attributes.append( QVariant( fields.at( i ).type() ) );
}
feature.setAttributes( attributes );
}
}
}

QList<QgsVectorLayer *> QgsVectorLayerUtils::QgsDuplicateFeatureContext::layers() const
{
QList<QgsVectorLayer *> layers;
Expand Down
10 changes: 10 additions & 0 deletions src/core/qgsvectorlayerutils.h
Expand Up @@ -167,6 +167,16 @@ class CORE_EXPORT QgsVectorLayerUtils
* \since QGIS 3.4
*/
static std::unique_ptr<QgsVectorLayerFeatureSource> getFeatureSource( QPointer<QgsVectorLayer> layer ) SIP_SKIP;

/**
* Matches the attributes in \a feature to the specified \a fields.
*
* This causes the attributes contained within the given \a feature to be rearranged (or in
* some cases dropped) in order to match the fields and order indicated by \a fields.
*
* \since QGIS 3.4
*/
static void matchAttributesToFields( QgsFeature &feature, const QgsFields &fields );
};


Expand Down

0 comments on commit a879400

Please sign in to comment.