Skip to content

Commit a879400

Browse files
committedSep 24, 2018
Add method to match feature attributes to the given fields
Refs #18784
1 parent 81487f9 commit a879400

File tree

3 files changed

+58
-0
lines changed

3 files changed

+58
-0
lines changed
 

‎python/core/auto_generated/qgsvectorlayerutils.sip.in

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,16 @@ The duplicated feature will be automatically inserted into the layer.
156156
.. versionadded:: 3.0
157157
%End
158158

159+
160+
static void matchAttributesToFields( QgsFeature &feature, const QgsFields &fields );
161+
%Docstring
162+
Matches the attributes in ``feature`` to the specified ``fields``.
163+
164+
This causes the attributes contained within the given ``feature`` to be rearranged (or in
165+
some cases dropped) in order to match the fields and order indicated by ``fields``.
166+
167+
.. versionadded:: 3.4
168+
%End
159169
};
160170

161171

‎src/core/qgsvectorlayerutils.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,44 @@ std::unique_ptr<QgsVectorLayerFeatureSource> QgsVectorLayerUtils::getFeatureSour
522522
return featureSource;
523523
}
524524

525+
void QgsVectorLayerUtils::matchAttributesToFields( QgsFeature &feature, const QgsFields &fields )
526+
{
527+
if ( !feature.fields().isEmpty() )
528+
{
529+
QgsAttributes attributes;
530+
attributes.reserve( fields.size() );
531+
// feature has a field mapping, so we can match attributes to field names
532+
for ( const QgsField &field : fields )
533+
{
534+
int index = feature.fields().lookupField( field.name() );
535+
attributes.append( index >= 0 ? feature.attribute( index ) : QVariant( field.type() ) );
536+
}
537+
feature.setAttributes( attributes );
538+
}
539+
else
540+
{
541+
// no field name mapping in feature, just use order
542+
const int lengthDiff = feature.attributes().count() - fields.count();
543+
if ( lengthDiff > 0 )
544+
{
545+
// truncate extra attributes
546+
QgsAttributes attributes = feature.attributes().mid( 0, fields.count() );
547+
feature.setAttributes( attributes );
548+
}
549+
else if ( lengthDiff < 0 )
550+
{
551+
// add missing null attributes
552+
QgsAttributes attributes = feature.attributes();
553+
attributes.reserve( fields.count() );
554+
for ( int i = feature.attributes().count(); i < fields.count(); ++i )
555+
{
556+
attributes.append( QVariant( fields.at( i ).type() ) );
557+
}
558+
feature.setAttributes( attributes );
559+
}
560+
}
561+
}
562+
525563
QList<QgsVectorLayer *> QgsVectorLayerUtils::QgsDuplicateFeatureContext::layers() const
526564
{
527565
QList<QgsVectorLayer *> layers;

‎src/core/qgsvectorlayerutils.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,16 @@ class CORE_EXPORT QgsVectorLayerUtils
167167
* \since QGIS 3.4
168168
*/
169169
static std::unique_ptr<QgsVectorLayerFeatureSource> getFeatureSource( QPointer<QgsVectorLayer> layer ) SIP_SKIP;
170+
171+
/**
172+
* Matches the attributes in \a feature to the specified \a fields.
173+
*
174+
* This causes the attributes contained within the given \a feature to be rearranged (or in
175+
* some cases dropped) in order to match the fields and order indicated by \a fields.
176+
*
177+
* \since QGIS 3.4
178+
*/
179+
static void matchAttributesToFields( QgsFeature &feature, const QgsFields &fields );
170180
};
171181

172182

0 commit comments

Comments
 (0)
Please sign in to comment.