QGIS API Documentation  3.0.2-Girona (307d082)
qgsvectorlayerutils.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsvectorlayerutils.cpp
3  -----------------------
4  Date : October 2016
5  Copyright : (C) 2016 by Nyall Dawson
6  Email : nyall dot dawson at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include <QRegularExpression>
17 
18 #include "qgsexpressioncontext.h"
19 #include "qgsfeatureiterator.h"
20 #include "qgsfeaturerequest.h"
21 #include "qgsvectorlayerutils.h"
22 #include "qgsvectordataprovider.h"
23 #include "qgsproject.h"
24 #include "qgsrelationmanager.h"
25 #include "qgsfeedback.h"
26 
27 QgsFeatureIterator QgsVectorLayerUtils::getValuesIterator( const QgsVectorLayer *layer, const QString &fieldOrExpression, bool &ok, bool selectedOnly )
28 {
29  std::unique_ptr<QgsExpression> expression;
30  QgsExpressionContext context;
31 
32  int attrNum = layer->fields().lookupField( fieldOrExpression );
33  if ( attrNum == -1 )
34  {
35  // try to use expression
36  expression.reset( new QgsExpression( fieldOrExpression ) );
38 
39  if ( expression->hasParserError() || !expression->prepare( &context ) )
40  {
41  ok = false;
42  return QgsFeatureIterator();
43  }
44  }
45 
46  QSet<QString> lst;
47  if ( !expression )
48  lst.insert( fieldOrExpression );
49  else
50  lst = expression->referencedColumns();
51 
53  .setFlags( ( expression && expression->needsGeometry() ) ?
56  .setSubsetOfAttributes( lst, layer->fields() );
57 
58  ok = true;
59  if ( !selectedOnly )
60  {
61  return layer->getFeatures( request );
62  }
63  else
64  {
65  return layer->getSelectedFeatures( request );
66  }
67 }
68 
69 QList<QVariant> QgsVectorLayerUtils::getValues( const QgsVectorLayer *layer, const QString &fieldOrExpression, bool &ok, bool selectedOnly, QgsFeedback *feedback )
70 {
71  QList<QVariant> values;
72  QgsFeatureIterator fit = getValuesIterator( layer, fieldOrExpression, ok, selectedOnly );
73  if ( ok )
74  {
75  std::unique_ptr<QgsExpression> expression;
76  QgsExpressionContext context;
77 
78  int attrNum = layer->fields().lookupField( fieldOrExpression );
79  if ( attrNum == -1 )
80  {
81  // use expression, already validated in the getValuesIterator() function
82  expression.reset( new QgsExpression( fieldOrExpression ) );
84  }
85 
86  QgsFeature f;
87  while ( fit.nextFeature( f ) )
88  {
89  if ( expression )
90  {
91  context.setFeature( f );
92  QVariant v = expression->evaluate( &context );
93  values << v;
94  }
95  else
96  {
97  values << f.attribute( attrNum );
98  }
99  if ( feedback && feedback->isCanceled() )
100  {
101  ok = false;
102  return values;
103  }
104  }
105  }
106  return values;
107 }
108 
109 QList<double> QgsVectorLayerUtils::getDoubleValues( const QgsVectorLayer *layer, const QString &fieldOrExpression, bool &ok, bool selectedOnly, int *nullCount, QgsFeedback *feedback )
110 {
111  QList<double> values;
112 
113  if ( nullCount )
114  *nullCount = 0;
115 
116  QList<QVariant> variantValues = getValues( layer, fieldOrExpression, ok, selectedOnly, feedback );
117  if ( !ok )
118  return values;
119 
120  bool convertOk;
121  Q_FOREACH ( const QVariant &value, variantValues )
122  {
123  double val = value.toDouble( &convertOk );
124  if ( convertOk )
125  values << val;
126  else if ( value.isNull() )
127  {
128  if ( nullCount )
129  *nullCount += 1;
130  }
131  if ( feedback && feedback->isCanceled() )
132  {
133  ok = false;
134  return values;
135  }
136  }
137  return values;
138 }
139 
140 bool QgsVectorLayerUtils::valueExists( const QgsVectorLayer *layer, int fieldIndex, const QVariant &value, const QgsFeatureIds &ignoreIds )
141 {
142  if ( !layer )
143  return false;
144 
145  QgsFields fields = layer->fields();
146 
147  if ( fieldIndex < 0 || fieldIndex >= fields.count() )
148  return false;
149 
150  QString fieldName = fields.at( fieldIndex ).name();
151 
152  // build up an optimised feature request
153  QgsFeatureRequest request;
156 
157  // at most we need to check ignoreIds.size() + 1 - the feature not in ignoreIds is the one we're interested in
158  int limit = ignoreIds.size() + 1;
159  request.setLimit( limit );
160 
161  request.setFilterExpression( QStringLiteral( "%1=%2" ).arg( QgsExpression::quotedColumnRef( fieldName ),
162  QgsExpression::quotedValue( value ) ) );
163 
164  QgsFeature feat;
165  QgsFeatureIterator it = layer->getFeatures( request );
166  while ( it.nextFeature( feat ) )
167  {
168  if ( ignoreIds.contains( feat.id() ) )
169  continue;
170 
171  return true;
172  }
173 
174  return false;
175 }
176 
177 QVariant QgsVectorLayerUtils::createUniqueValue( const QgsVectorLayer *layer, int fieldIndex, const QVariant &seed )
178 {
179  if ( !layer )
180  return QVariant();
181 
182  QgsFields fields = layer->fields();
183 
184  if ( fieldIndex < 0 || fieldIndex >= fields.count() )
185  return QVariant();
186 
187  QgsField field = fields.at( fieldIndex );
188 
189  if ( field.isNumeric() )
190  {
191  QVariant maxVal = layer->maximumValue( fieldIndex );
192  QVariant newVar( maxVal.toLongLong() + 1 );
193  if ( field.convertCompatible( newVar ) )
194  return newVar;
195  else
196  return QVariant();
197  }
198  else
199  {
200  switch ( field.type() )
201  {
202  case QVariant::String:
203  {
204  QString base;
205  if ( seed.isValid() )
206  base = seed.toString();
207 
208  if ( !base.isEmpty() )
209  {
210  // strip any existing _1, _2 from the seed
211  QRegularExpression rx( QStringLiteral( "(.*)_\\d+" ) );
212  QRegularExpressionMatch match = rx.match( base );
213  if ( match.hasMatch() )
214  {
215  base = match.captured( 1 );
216  }
217  }
218  else
219  {
220  // no base seed - fetch first value from layer
221  QgsFeatureRequest req;
222  req.setLimit( 1 );
223  req.setSubsetOfAttributes( QgsAttributeList() << fieldIndex );
225  QgsFeature f;
226  layer->getFeatures( req ).nextFeature( f );
227  base = f.attribute( fieldIndex ).toString();
228  }
229 
230  // try variants like base_1, base_2, etc until a new value found
231  QStringList vals = layer->uniqueStringsMatching( fieldIndex, base );
232 
233  // might already be unique
234  if ( !base.isEmpty() && !vals.contains( base ) )
235  return base;
236 
237  for ( int i = 1; i < 10000; ++i )
238  {
239  QString testVal = base + '_' + QString::number( i );
240  if ( !vals.contains( testVal ) )
241  return testVal;
242  }
243 
244  // failed
245  return QVariant();
246  }
247 
248  default:
249  // todo other types - dates? times?
250  break;
251  }
252  }
253 
254  return QVariant();
255 }
256 
257 bool QgsVectorLayerUtils::validateAttribute( const QgsVectorLayer *layer, const QgsFeature &feature, int attributeIndex, QStringList &errors,
259 {
260  if ( !layer )
261  return false;
262 
263  if ( attributeIndex < 0 || attributeIndex >= layer->fields().count() )
264  return false;
265 
266  QgsFields fields = layer->fields();
267  QgsField field = fields.at( attributeIndex );
268  QVariant value = feature.attribute( attributeIndex );
269  bool valid = true;
270  errors.clear();
271 
272  QgsFieldConstraints constraints = field.constraints();
273 
274  if ( constraints.constraints() & QgsFieldConstraints::ConstraintExpression && !constraints.constraintExpression().isEmpty()
277  {
279  context.setFeature( feature );
280 
281  QgsExpression expr( constraints.constraintExpression() );
282 
283  valid = expr.evaluate( &context ).toBool();
284 
285  if ( expr.hasParserError() )
286  {
287  errors << QObject::tr( "parser error: %1" ).arg( expr.parserErrorString() );
288  }
289  else if ( expr.hasEvalError() )
290  {
291  errors << QObject::tr( "evaluation error: %1" ).arg( expr.evalErrorString() );
292  }
293  else if ( !valid )
294  {
295  errors << QObject::tr( "%1 check failed" ).arg( constraints.constraintDescription() );
296  }
297  }
298 
302  {
303  bool exempt = false;
304  if ( fields.fieldOrigin( attributeIndex ) == QgsFields::OriginProvider
306  {
307  int providerIdx = fields.fieldOriginIndex( attributeIndex );
308  exempt = layer->dataProvider()->skipConstraintCheck( providerIdx, QgsFieldConstraints::ConstraintNotNull, value );
309  }
310 
311  if ( !exempt )
312  {
313  valid = valid && !value.isNull();
314 
315  if ( value.isNull() )
316  {
317  errors << QObject::tr( "value is NULL" );
318  }
319  }
320  }
321 
325  {
326  bool exempt = false;
327  if ( fields.fieldOrigin( attributeIndex ) == QgsFields::OriginProvider
329  {
330  int providerIdx = fields.fieldOriginIndex( attributeIndex );
331  exempt = layer->dataProvider()->skipConstraintCheck( providerIdx, QgsFieldConstraints::ConstraintUnique, value );
332  }
333 
334  if ( !exempt )
335  {
336  bool alreadyExists = QgsVectorLayerUtils::valueExists( layer, attributeIndex, value, QgsFeatureIds() << feature.id() );
337  valid = valid && !alreadyExists;
338 
339  if ( alreadyExists )
340  {
341  errors << QObject::tr( "value is not unique" );
342  }
343  }
344  }
345 
346  return valid;
347 }
348 
350  const QgsAttributeMap &attributes, QgsExpressionContext *context )
351 {
352  if ( !layer )
353  {
354  return QgsFeature();
355  }
356 
357  QgsExpressionContext *evalContext = context;
358  std::unique_ptr< QgsExpressionContext > tempContext;
359  if ( !evalContext )
360  {
361  // no context passed, so we create a default one
363  evalContext = tempContext.get();
364  }
365 
366  QgsFields fields = layer->fields();
367 
368  QgsFeature newFeature( fields );
369  newFeature.setValid( true );
370  newFeature.setGeometry( geometry );
371 
372  // initialize attributes
373  newFeature.initAttributes( fields.count() );
374  for ( int idx = 0; idx < fields.count(); ++idx )
375  {
376  QVariant v;
377  bool checkUnique = true;
378 
379  // in order of priority:
380 
381  // 1. client side default expression
382  if ( layer->defaultValueDefinition( idx ).isValid() )
383  {
384  // client side default expression set - takes precedence over all. Why? Well, this is the only default
385  // which QGIS users have control over, so we assume that they're deliberately overriding any
386  // provider defaults for some good reason and we should respect that
387  v = layer->defaultValue( idx, newFeature, evalContext );
388  }
389 
390  // 2. provider side default value clause
391  // note - not an else if deliberately. Users may return null from a default value expression to fallback to provider defaults
392  if ( !v.isValid() && fields.fieldOrigin( idx ) == QgsFields::OriginProvider )
393  {
394  int providerIndex = fields.fieldOriginIndex( idx );
395  QString providerDefault = layer->dataProvider()->defaultValueClause( providerIndex );
396  if ( !providerDefault.isEmpty() )
397  {
398  v = providerDefault;
399  checkUnique = false;
400  }
401  }
402 
403  // 3. provider side default literal
404  // note - deliberately not using else if!
405  if ( !v.isValid() && fields.fieldOrigin( idx ) == QgsFields::OriginProvider )
406  {
407  int providerIndex = fields.fieldOriginIndex( idx );
408  v = layer->dataProvider()->defaultValue( providerIndex );
409  if ( v.isValid() )
410  {
411  //trust that the provider default has been sensibly set not to violate any constraints
412  checkUnique = false;
413  }
414  }
415 
416  // 4. passed attribute value
417  // note - deliberately not using else if!
418  if ( !v.isValid() && attributes.contains( idx ) )
419  {
420  v = attributes.value( idx );
421  }
422 
423  // last of all... check that unique constraints are respected
424  // we can't handle not null or expression constraints here, since there's no way to pick a sensible
425  // value if the constraint is violated
426  if ( checkUnique && fields.at( idx ).constraints().constraints() & QgsFieldConstraints::ConstraintUnique )
427  {
428  if ( QgsVectorLayerUtils::valueExists( layer, idx, v ) )
429  {
430  // unique constraint violated
431  QVariant uniqueValue = QgsVectorLayerUtils::createUniqueValue( layer, idx, v );
432  if ( uniqueValue.isValid() )
433  v = uniqueValue;
434  }
435  }
436 
437  newFeature.setAttribute( idx, v );
438  }
439 
440  return newFeature;
441 }
442 
443 QgsFeature QgsVectorLayerUtils::duplicateFeature( QgsVectorLayer *layer, const QgsFeature &feature, QgsProject *project, int depth, QgsDuplicateFeatureContext &duplicateFeatureContext )
444 {
445  if ( !layer )
446  return QgsFeature();
447 
448  if ( !layer->isEditable() )
449  return QgsFeature();
450 
451  //get context from layer
453  context.setFeature( feature );
454 
455  //create the attribute map
456  QgsAttributes srcAttr = feature.attributes();
457  QgsAttributeMap dstAttr;
458  for ( int src = 0; src < srcAttr.count(); ++src )
459  {
460  dstAttr[ src ] = srcAttr.at( src );
461  }
462 
463  QgsFeature newFeature = createFeature( layer, feature.geometry(), dstAttr, &context );
464 
465  const QList<QgsRelation> relations = project->relationManager()->referencedRelations( layer );
466 
467  for ( const QgsRelation &relation : relations )
468  {
469  //check if composition (and not association)
470  if ( relation.strength() == QgsRelation::Composition && depth < 1 )
471  {
472  depth++;
473  //get features connected over this relation
474  QgsFeatureIterator relatedFeaturesIt = relation.getRelatedFeatures( feature );
475  QgsFeatureIds childFeatureIds;
476  QgsFeature childFeature;
477  while ( relatedFeaturesIt.nextFeature( childFeature ) )
478  {
479  //set childlayer editable
480  relation.referencingLayer()->startEditing();
481  //change the fk of the child to the id of the new parent
482  const auto pairs = relation.fieldPairs();
483  for ( const QgsRelation::FieldPair &fieldPair : pairs )
484  {
485  childFeature.setAttribute( fieldPair.first, newFeature.attribute( fieldPair.second ) );
486  }
487  //call the function for the child
488  childFeatureIds.insert( duplicateFeature( relation.referencingLayer(), childFeature, project, depth, duplicateFeatureContext ).id() );
489  }
490 
491  //store for feedback
492  duplicateFeatureContext.setDuplicatedFeatures( relation.referencingLayer(), childFeatureIds );
493  }
494  }
495 
496  layer->addFeature( newFeature );
497 
498  return newFeature;
499 }
500 
502 {
503  QList<QgsVectorLayer *> layers;
504  QMap<QgsVectorLayer *, QgsFeatureIds>::const_iterator i;
505  for ( i = mDuplicatedFeatures.begin(); i != mDuplicatedFeatures.end(); ++i )
506  layers.append( i.key() );
507  return layers;
508 }
509 
511 {
512  return mDuplicatedFeatures[layer];
513 }
514 
515 void QgsVectorLayerUtils::QgsDuplicateFeatureContext::setDuplicatedFeatures( QgsVectorLayer *layer, const QgsFeatureIds &ids )
516 {
517  mDuplicatedFeatures.insert( layer, ids );
518 }
519 /*
520 QMap<QgsVectorLayer *, QgsFeatureIds> QgsVectorLayerUtils::QgsDuplicateFeatureContext::duplicateFeatureContext() const
521 {
522  return mDuplicatedFeatures;
523 }
524 */
int lookupField(const QString &fieldName) const
Look up field&#39;s index from the field name.
Definition: qgsfields.cpp:299
QgsFeatureId id
Definition: qgsfeature.h:71
Wrapper for iterator of features from vector data provider or vector layer.
static QgsFeature createFeature(QgsVectorLayer *layer, const QgsGeometry &geometry=QgsGeometry(), const QgsAttributeMap &attributes=QgsAttributeMap(), QgsExpressionContext *context=nullptr)
Creates a new feature ready for insertion into a layer.
static bool valueExists(const QgsVectorLayer *layer, int fieldIndex, const QVariant &value, const QgsFeatureIds &ignoreIds=QgsFeatureIds())
Returns true if the specified value already exists within a field.
FieldOrigin fieldOrigin(int fieldIdx) const
Get field&#39;s origin (value from an enumeration)
Definition: qgsfields.cpp:171
ConstraintStrength constraintStrength(Constraint constraint) const
Returns the strength of a field constraint, or ConstraintStrengthNotSet if the constraint is not pres...
QString name
Definition: qgsfield.h:57
bool isValid() const
Returns if this default value should be applied.
Contains mainly the QMap with QgsVectorLayer and QgsFeatureIds do list all the duplicated features...
QList< QgsVectorLayer * > layers() const
Returns all the layers on which features have been duplicated.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeature.h:544
ConstraintOrigin
Origin of constraints.
static QList< double > getDoubleValues(const QgsVectorLayer *layer, const QString &fieldOrExpression, bool &ok, bool selectedOnly=false, int *nullCount=nullptr, QgsFeedback *feedback=nullptr)
Fetches all double values from a specified field name or expression.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
bool convertCompatible(QVariant &v) const
Converts the provided variant to a compatible format.
Definition: qgsfield.cpp:223
Container of fields for a vector layer.
Definition: qgsfields.h:42
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:111
bool setAttribute(int field, const QVariant &attr)
Set an attribute&#39;s value by field index.
Definition: qgsfeature.cpp:204
static QList< QVariant > getValues(const QgsVectorLayer *layer, const QString &fieldOrExpression, bool &ok, bool selectedOnly=false, QgsFeedback *feedback=nullptr)
Fetches all values from a specified field name or expression.
Stores information about constraints which may be present on a field.
Field comes from the underlying data provider of the vector layer (originIndex = index in provider&#39;s ...
Definition: qgsfields.h:49
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:62
static bool validateAttribute(const QgsVectorLayer *layer, const QgsFeature &feature, int attributeIndex, QStringList &errors, QgsFieldConstraints::ConstraintStrength strength=QgsFieldConstraints::ConstraintStrengthNotSet, QgsFieldConstraints::ConstraintOrigin origin=QgsFieldConstraints::ConstraintOriginNotSet)
Tests an attribute value to check whether it passes all constraints which are present on the correspo...
bool isEditable() const override
Returns true if the provider is in editing mode.
int count() const
Return number of items.
Definition: qgsfields.cpp:115
static QgsFeatureIterator getValuesIterator(const QgsVectorLayer *layer, const QString &fieldOrExpression, bool &ok, bool selectedOnly)
Create a feature iterator for a specified field name or expression.
Constraint was set at data provider.
Field has an expression constraint set. See constraintExpression().
QgsField at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfields.cpp:145
int fieldOriginIndex(int fieldIdx) const
Get field&#39;s origin index (its meaning is specific to each type of origin)
Definition: qgsfields.cpp:179
Base class for feedback objects to be used for cancelation of something running in a worker thread...
Definition: qgsfeedback.h:44
virtual bool skipConstraintCheck(int fieldIndex, QgsFieldConstraints::Constraint constraint, const QVariant &value=QVariant()) const
Returns true if a constraint check should be skipped for a specified field (e.g., if the value return...
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
QStringList uniqueStringsMatching(int index, const QString &substring, int limit=-1, QgsFeedback *feedback=nullptr) const
Returns unique string values of an attribute which contain a specified subset string.
Defines a relation between matching fields of the two involved tables of a relation.
Definition: qgsrelation.h:72
QgsFields fields() const override
Returns the list of fields of this layer.
QgsFeatureIterator getSelectedFeatures(QgsFeatureRequest request=QgsFeatureRequest()) const
Get an iterator of the selected features.
QString constraintDescription() const
Returns the descriptive name for the constraint expression.
void initAttributes(int fieldCount)
Initialize this feature with the given number of fields.
Definition: qgsfeature.cpp:195
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void seed(uint32_t value)
QMap< int, QVariant > QgsAttributeMap
Definition: qgsattributes.h:39
This class wraps a request for features to a vector layer (or directly its vector data provider)...
virtual QString defaultValueClause(int fieldIndex) const
Returns any default value clauses which are present at the provider for a specified field index...
Reads and writes project states.
Definition: qgsproject.h:82
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer&#39;s project and layer.
QList< QgsRelation > referencedRelations(QgsVectorLayer *layer=nullptr) const
Get all relations where this layer is the referenced part (i.e.
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:48
QgsGeometry geometry() const
Returns the geometry associated with this feature.
Definition: qgsfeature.cpp:101
QgsRelationManager relationManager
Definition: qgsproject.h:92
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const override
Query the layer for features specified in request.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
static QVariant createUniqueValue(const QgsVectorLayer *layer, int fieldIndex, const QVariant &seed=QVariant())
Returns a new attribute value for the specified field index which is guaranteed to be unique...
void setValid(bool validity)
Sets the validity of the feature.
Definition: qgsfeature.cpp:181
QgsDefaultValue defaultValueDefinition(int index) const
Returns the definition of the expression used when calculating the default value for a field...
QVariant maximumValue(int index) const override
Returns the maximum value for an attribute column or an invalid variant in case of error...
QgsFieldConstraints constraints
Definition: qgsfield.h:60
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:54
ConstraintStrength
Strength of constraints.
static QgsFeature duplicateFeature(QgsVectorLayer *layer, const QgsFeature &feature, QgsProject *project, int depth, QgsDuplicateFeatureContext &duplicateFeatureContext)
Duplicates a feature and it&#39;s children (one level deep).
QgsFeatureIds duplicatedFeatures(QgsVectorLayer *layer) const
Returns the duplicated features in the given layer.
void setGeometry(const QgsGeometry &geometry)
Set the feature&#39;s geometry.
Definition: qgsfeature.cpp:137
QgsVectorDataProvider * dataProvider() override
Returns the layer&#39;s data provider.
QgsFeatureRequest & setLimit(long limit)
Set the maximum number of features to request.
bool isNumeric
Definition: qgsfield.h:52
ConstraintOrigin constraintOrigin(Constraint constraint) const
Returns the origin of a field constraint, or ConstraintOriginNotSet if the constraint is not present ...
void appendScopes(const QList< QgsExpressionContextScope *> &scopes)
Appends a list of scopes to the end of the context.
QList< int > QgsAttributeList
Definition: qgsfield.h:27
bool nextFeature(QgsFeature &f)
QString constraintExpression() const
Returns the constraint expression for the field, if set.
Geometry is not required. It may still be returned if e.g. required for a filter condition.
A vector of attributes.
Definition: qgsattributes.h:58
Represents a vector layer which manages a vector based data sets.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:255
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=nullptr) override
Adds a single feature to the sink.
QVariant::Type type
Definition: qgsfield.h:55
QgsAttributes attributes
Definition: qgsfeature.h:72
Fix relation, related elements are part of the parent and a parent copy will copy any children or del...
Definition: qgsrelation.h:58
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Set flags that affect how features will be fetched.
QVariant defaultValue(int index, const QgsFeature &feature=QgsFeature(), QgsExpressionContext *context=nullptr) const
Returns the calculated default value for the specified field index.
Field must have a unique value.
virtual QVariant defaultValue(int fieldIndex) const
Returns any literal default values which are present at the provider for a specified field index...