QGIS API Documentation  3.17.0-Master (a035f434f4)
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 #include "qgsvectorlayer.h"
27 #include "qgsthreadingutils.h"
28 #include "qgsgeometrycollection.h"
30 #include "qgsmultisurface.h"
31 #include "qgsgeometryfactory.h"
32 #include "qgscurvepolygon.h"
33 #include "qgspolygon.h"
34 #include "qgslinestring.h"
35 #include "qgsmultipoint.h"
37 #include "qgsvectorlayerlabeling.h"
38 #include "qgspallabeling.h"
39 #include "qgsrenderer.h"
40 #include "qgssymbollayer.h"
41 #include "qgsstyleentityvisitor.h"
42 #include "qgsstyle.h"
43 #include "qgsauxiliarystorage.h"
44 
45 
46 QgsFeatureIterator QgsVectorLayerUtils::getValuesIterator( const QgsVectorLayer *layer, const QString &fieldOrExpression, bool &ok, bool selectedOnly )
47 {
48  std::unique_ptr<QgsExpression> expression;
49  QgsExpressionContext context;
50 
51  int attrNum = layer->fields().lookupField( fieldOrExpression );
52  if ( attrNum == -1 )
53  {
54  // try to use expression
55  expression.reset( new QgsExpression( fieldOrExpression ) );
57 
58  if ( expression->hasParserError() || !expression->prepare( &context ) )
59  {
60  ok = false;
61  return QgsFeatureIterator();
62  }
63  }
64 
65  QSet<QString> lst;
66  if ( !expression )
67  lst.insert( fieldOrExpression );
68  else
69  lst = expression->referencedColumns();
70 
72  .setFlags( ( expression && expression->needsGeometry() ) ?
75  .setSubsetOfAttributes( lst, layer->fields() );
76 
77  ok = true;
78  if ( !selectedOnly )
79  {
80  return layer->getFeatures( request );
81  }
82  else
83  {
84  return layer->getSelectedFeatures( request );
85  }
86 }
87 
88 QList<QVariant> QgsVectorLayerUtils::getValues( const QgsVectorLayer *layer, const QString &fieldOrExpression, bool &ok, bool selectedOnly, QgsFeedback *feedback )
89 {
90  QList<QVariant> values;
91  QgsFeatureIterator fit = getValuesIterator( layer, fieldOrExpression, ok, selectedOnly );
92  if ( ok )
93  {
94  std::unique_ptr<QgsExpression> expression;
95  QgsExpressionContext context;
96 
97  int attrNum = layer->fields().lookupField( fieldOrExpression );
98  if ( attrNum == -1 )
99  {
100  // use expression, already validated in the getValuesIterator() function
101  expression.reset( new QgsExpression( fieldOrExpression ) );
103  }
104 
105  QgsFeature f;
106  while ( fit.nextFeature( f ) )
107  {
108  if ( expression )
109  {
110  context.setFeature( f );
111  QVariant v = expression->evaluate( &context );
112  values << v;
113  }
114  else
115  {
116  values << f.attribute( attrNum );
117  }
118  if ( feedback && feedback->isCanceled() )
119  {
120  ok = false;
121  return values;
122  }
123  }
124  }
125  return values;
126 }
127 
128 QList<double> QgsVectorLayerUtils::getDoubleValues( const QgsVectorLayer *layer, const QString &fieldOrExpression, bool &ok, bool selectedOnly, int *nullCount, QgsFeedback *feedback )
129 {
130  QList<double> values;
131 
132  if ( nullCount )
133  *nullCount = 0;
134 
135  QList<QVariant> variantValues = getValues( layer, fieldOrExpression, ok, selectedOnly, feedback );
136  if ( !ok )
137  return values;
138 
139  bool convertOk;
140  const auto constVariantValues = variantValues;
141  for ( const QVariant &value : constVariantValues )
142  {
143  double val = value.toDouble( &convertOk );
144  if ( convertOk )
145  values << val;
146  else if ( value.isNull() )
147  {
148  if ( nullCount )
149  *nullCount += 1;
150  }
151  if ( feedback && feedback->isCanceled() )
152  {
153  ok = false;
154  return values;
155  }
156  }
157  return values;
158 }
159 
160 bool QgsVectorLayerUtils::valueExists( const QgsVectorLayer *layer, int fieldIndex, const QVariant &value, const QgsFeatureIds &ignoreIds )
161 {
162  if ( !layer )
163  return false;
164 
165  QgsFields fields = layer->fields();
166 
167  if ( fieldIndex < 0 || fieldIndex >= fields.count() )
168  return false;
169 
170  // If it's a joined field search the value in the source layer
171  if ( fields.fieldOrigin( fieldIndex ) == QgsFields::FieldOrigin::OriginJoin )
172  {
173  int srcFieldIndex;
174  const QgsVectorLayerJoinInfo *joinInfo { layer->joinBuffer()->joinForFieldIndex( fieldIndex, fields, srcFieldIndex ) };
175  if ( ! joinInfo )
176  {
177  return false;
178  }
179  fieldIndex = srcFieldIndex;
180  layer = joinInfo->joinLayer();
181  if ( ! layer )
182  {
183  return false;
184  }
185  fields = layer->fields();
186  }
187 
188  QString fieldName = fields.at( fieldIndex ).name();
189 
190  // build up an optimised feature request
191  QgsFeatureRequest request;
192  request.setNoAttributes();
194 
195  // at most we need to check ignoreIds.size() + 1 - the feature not in ignoreIds is the one we're interested in
196  int limit = ignoreIds.size() + 1;
197  request.setLimit( limit );
198 
199  request.setFilterExpression( QStringLiteral( "%1=%2" ).arg( QgsExpression::quotedColumnRef( fieldName ),
200  QgsExpression::quotedValue( value ) ) );
201 
202  QgsFeature feat;
203  QgsFeatureIterator it = layer->getFeatures( request );
204  while ( it.nextFeature( feat ) )
205  {
206  if ( ignoreIds.contains( feat.id() ) )
207  continue;
208 
209  return true;
210  }
211 
212  return false;
213 }
214 
215 QVariant QgsVectorLayerUtils::createUniqueValue( const QgsVectorLayer *layer, int fieldIndex, const QVariant &seed )
216 {
217  if ( !layer )
218  return QVariant();
219 
220  QgsFields fields = layer->fields();
221 
222  if ( fieldIndex < 0 || fieldIndex >= fields.count() )
223  return QVariant();
224 
225  QgsField field = fields.at( fieldIndex );
226 
227  if ( field.isNumeric() )
228  {
229  QVariant maxVal = layer->maximumValue( fieldIndex );
230  QVariant newVar( maxVal.toLongLong() + 1 );
231  if ( field.convertCompatible( newVar ) )
232  return newVar;
233  else
234  return QVariant();
235  }
236  else
237  {
238  switch ( field.type() )
239  {
240  case QVariant::String:
241  {
242  QString base;
243  if ( seed.isValid() )
244  base = seed.toString();
245 
246  if ( !base.isEmpty() )
247  {
248  // strip any existing _1, _2 from the seed
249  QRegularExpression rx( QStringLiteral( "(.*)_\\d+" ) );
250  QRegularExpressionMatch match = rx.match( base );
251  if ( match.hasMatch() )
252  {
253  base = match.captured( 1 );
254  }
255  }
256  else
257  {
258  // no base seed - fetch first value from layer
259  QgsFeatureRequest req;
260  req.setLimit( 1 );
261  req.setSubsetOfAttributes( QgsAttributeList() << fieldIndex );
263  QgsFeature f;
264  layer->getFeatures( req ).nextFeature( f );
265  base = f.attribute( fieldIndex ).toString();
266  }
267 
268  // try variants like base_1, base_2, etc until a new value found
269  QStringList vals = layer->uniqueStringsMatching( fieldIndex, base );
270 
271  // might already be unique
272  if ( !base.isEmpty() && !vals.contains( base ) )
273  return base;
274 
275  for ( int i = 1; i < 10000; ++i )
276  {
277  QString testVal = base + '_' + QString::number( i );
278  if ( !vals.contains( testVal ) )
279  return testVal;
280  }
281 
282  // failed
283  return QVariant();
284  }
285 
286  default:
287  // todo other types - dates? times?
288  break;
289  }
290  }
291 
292  return QVariant();
293 }
294 
295 QVariant QgsVectorLayerUtils::createUniqueValueFromCache( const QgsVectorLayer *layer, int fieldIndex, const QSet<QVariant> &existingValues, const QVariant &seed )
296 {
297  if ( !layer )
298  return QVariant();
299 
300  QgsFields fields = layer->fields();
301 
302  if ( fieldIndex < 0 || fieldIndex >= fields.count() )
303  return QVariant();
304 
305  QgsField field = fields.at( fieldIndex );
306 
307  if ( field.isNumeric() )
308  {
309  QVariant maxVal = existingValues.isEmpty() ? 0 : *std::max_element( existingValues.begin(), existingValues.end() );
310  QVariant newVar( maxVal.toLongLong() + 1 );
311  if ( field.convertCompatible( newVar ) )
312  return newVar;
313  else
314  return QVariant();
315  }
316  else
317  {
318  switch ( field.type() )
319  {
320  case QVariant::String:
321  {
322  QString base;
323  if ( seed.isValid() )
324  base = seed.toString();
325 
326  if ( !base.isEmpty() )
327  {
328  // strip any existing _1, _2 from the seed
329  QRegularExpression rx( QStringLiteral( "(.*)_\\d+" ) );
330  QRegularExpressionMatch match = rx.match( base );
331  if ( match.hasMatch() )
332  {
333  base = match.captured( 1 );
334  }
335  }
336  else
337  {
338  // no base seed - fetch first value from layer
339  QgsFeatureRequest req;
340  base = existingValues.isEmpty() ? QString() : existingValues.values().first().toString();
341  }
342 
343  // try variants like base_1, base_2, etc until a new value found
344  QStringList vals;
345  for ( const auto &v : qgis::as_const( existingValues ) )
346  {
347  if ( v.toString().startsWith( base ) )
348  vals.push_back( v.toString() );
349  }
350 
351  // might already be unique
352  if ( !base.isEmpty() && !vals.contains( base ) )
353  return base;
354 
355  for ( int i = 1; i < 10000; ++i )
356  {
357  QString testVal = base + '_' + QString::number( i );
358  if ( !vals.contains( testVal ) )
359  return testVal;
360  }
361 
362  // failed
363  return QVariant();
364  }
365 
366  default:
367  // todo other types - dates? times?
368  break;
369  }
370  }
371 
372  return QVariant();
373 
374 }
375 
376 bool QgsVectorLayerUtils::validateAttribute( const QgsVectorLayer *layer, const QgsFeature &feature, int attributeIndex, QStringList &errors,
378 {
379  if ( !layer )
380  return false;
381 
382  if ( attributeIndex < 0 || attributeIndex >= layer->fields().count() )
383  return false;
384 
385  QgsFields fields = layer->fields();
386  QgsField field = fields.at( attributeIndex );
387  QVariant value = feature.attribute( attributeIndex );
388  bool valid = true;
389  errors.clear();
390 
391  QgsFieldConstraints constraints = field.constraints();
392 
393  if ( constraints.constraints() & QgsFieldConstraints::ConstraintExpression && !constraints.constraintExpression().isEmpty()
396  {
398  context.setFeature( feature );
399 
400  QgsExpression expr( constraints.constraintExpression() );
401 
402  valid = expr.evaluate( &context ).toBool();
403 
404  if ( expr.hasParserError() )
405  {
406  errors << QObject::tr( "parser error: %1" ).arg( expr.parserErrorString() );
407  }
408  else if ( expr.hasEvalError() )
409  {
410  errors << QObject::tr( "evaluation error: %1" ).arg( expr.evalErrorString() );
411  }
412  else if ( !valid )
413  {
414  errors << QObject::tr( "%1 check failed" ).arg( constraints.constraintDescription() );
415  }
416  }
417 
418  bool notNullConstraintViolated { false };
419 
423  {
424  bool exempt = false;
425  if ( fields.fieldOrigin( attributeIndex ) == QgsFields::OriginProvider
427  {
428  int providerIdx = fields.fieldOriginIndex( attributeIndex );
429  exempt = layer->dataProvider()->skipConstraintCheck( providerIdx, QgsFieldConstraints::ConstraintNotNull, value );
430  }
431 
432  if ( !exempt )
433  {
434  valid = valid && !value.isNull();
435 
436  if ( value.isNull() )
437  {
438  errors << QObject::tr( "value is NULL" );
439  notNullConstraintViolated = true;
440  }
441  }
442  }
443 
444  // if a NOT NULL constraint is violated we don't need to check for UNIQUE
445  if ( ! notNullConstraintViolated )
446  {
447 
451  {
452  bool exempt = false;
453  if ( fields.fieldOrigin( attributeIndex ) == QgsFields::OriginProvider
455  {
456  int providerIdx = fields.fieldOriginIndex( attributeIndex );
457  exempt = layer->dataProvider()->skipConstraintCheck( providerIdx, QgsFieldConstraints::ConstraintUnique, value );
458  }
459 
460  if ( !exempt )
461  {
462 
463  bool alreadyExists = QgsVectorLayerUtils::valueExists( layer, attributeIndex, value, QgsFeatureIds() << feature.id() );
464  valid = valid && !alreadyExists;
465 
466  if ( alreadyExists )
467  {
468  errors << QObject::tr( "value is not unique" );
469  }
470  }
471  }
472  }
473 
474  return valid;
475 }
476 
478  const QgsAttributeMap &attributes, QgsExpressionContext *context )
479 {
480  QgsFeatureList features { createFeatures( layer, QgsFeaturesDataList() << QgsFeatureData( geometry, attributes ), context ) };
481  return features.isEmpty() ? QgsFeature() : features.first();
482 }
483 
485 {
486  if ( !layer )
487  return QgsFeatureList();
488 
489  QgsFeatureList result;
490  result.reserve( featuresData.length() );
491 
492  QgsExpressionContext *evalContext = context;
493  std::unique_ptr< QgsExpressionContext > tempContext;
494  if ( !evalContext )
495  {
496  // no context passed, so we create a default one
498  evalContext = tempContext.get();
499  }
500 
501  QgsFields fields = layer->fields();
502 
503  // Cache unique values
504  QMap<int, QSet<QVariant>> uniqueValueCache;
505 
506  auto checkUniqueValue = [ & ]( const int fieldIdx, const QVariant & value )
507  {
508  if ( ! uniqueValueCache.contains( fieldIdx ) )
509  {
510  // If the layer is filtered, get unique values from an unfiltered clone
511  if ( ! layer->subsetString().isEmpty() )
512  {
513  std::unique_ptr<QgsVectorLayer> unfilteredClone { layer->clone( ) };
514  unfilteredClone->setSubsetString( QString( ) );
515  uniqueValueCache[ fieldIdx ] = unfilteredClone->uniqueValues( fieldIdx );
516  }
517  else
518  {
519  uniqueValueCache[ fieldIdx ] = layer->uniqueValues( fieldIdx );
520  }
521  }
522  return uniqueValueCache[ fieldIdx ].contains( value );
523  };
524 
525  for ( const auto &fd : qgis::as_const( featuresData ) )
526  {
527 
528  QgsFeature newFeature( fields );
529  newFeature.setValid( true );
530  newFeature.setGeometry( fd.geometry() );
531 
532  // initialize attributes
533  newFeature.initAttributes( fields.count() );
534  for ( int idx = 0; idx < fields.count(); ++idx )
535  {
536  QVariant v;
537  bool checkUnique = true;
538  const bool hasUniqueConstraint { static_cast<bool>( fields.at( idx ).constraints().constraints() & QgsFieldConstraints::ConstraintUnique ) };
539 
540  // in order of priority:
541  // 1. passed attribute value and if field does not have a unique constraint like primary key
542  if ( fd.attributes().contains( idx ) )
543  {
544  v = fd.attributes().value( idx );
545  }
546 
547  // 2. client side default expression
548  // note - deliberately not using else if!
549  QgsDefaultValue defaultValueDefinition = layer->defaultValueDefinition( idx );
550  if ( ( v.isNull() || ( hasUniqueConstraint
551  && checkUniqueValue( idx, v ) )
552  || defaultValueDefinition.applyOnUpdate() )
553  && defaultValueDefinition.isValid() )
554  {
555  // client side default expression set - takes precedence over all. Why? Well, this is the only default
556  // which QGIS users have control over, so we assume that they're deliberately overriding any
557  // provider defaults for some good reason and we should respect that
558  v = layer->defaultValue( idx, newFeature, evalContext );
559  }
560 
561  // 3. provider side default value clause
562  // note - not an else if deliberately. Users may return null from a default value expression to fallback to provider defaults
563  if ( ( v.isNull() || ( hasUniqueConstraint
564  && checkUniqueValue( idx, v ) ) )
565  && fields.fieldOrigin( idx ) == QgsFields::OriginProvider )
566  {
567  int providerIndex = fields.fieldOriginIndex( idx );
568  QString providerDefault = layer->dataProvider()->defaultValueClause( providerIndex );
569  if ( !providerDefault.isEmpty() )
570  {
571  v = providerDefault;
572  checkUnique = false;
573  }
574  }
575 
576  // 4. provider side default literal
577  // note - deliberately not using else if!
578  if ( ( v.isNull() || ( checkUnique
579  && hasUniqueConstraint
580  && checkUniqueValue( idx, v ) ) )
581  && fields.fieldOrigin( idx ) == QgsFields::OriginProvider )
582  {
583  int providerIndex = fields.fieldOriginIndex( idx );
584  v = layer->dataProvider()->defaultValue( providerIndex );
585  if ( v.isValid() )
586  {
587  //trust that the provider default has been sensibly set not to violate any constraints
588  checkUnique = false;
589  }
590  }
591 
592  // 5. passed attribute value
593  // note - deliberately not using else if!
594  if ( v.isNull() && fd.attributes().contains( idx ) )
595  {
596  v = fd.attributes().value( idx );
597  }
598 
599  // last of all... check that unique constraints are respected if the value is valid
600  if ( v.isValid() )
601  {
602  // we can't handle not null or expression constraints here, since there's no way to pick a sensible
603  // value if the constraint is violated
604  if ( checkUnique && hasUniqueConstraint )
605  {
606  if ( checkUniqueValue( idx, v ) )
607  {
608  // unique constraint violated
609  QVariant uniqueValue = QgsVectorLayerUtils::createUniqueValueFromCache( layer, idx, uniqueValueCache[ idx ], v );
610  if ( uniqueValue.isValid() )
611  v = uniqueValue;
612  }
613  }
614  if ( hasUniqueConstraint )
615  {
616  uniqueValueCache[ idx ].insert( v );
617  }
618  }
619  newFeature.setAttribute( idx, v );
620  }
621  result.append( newFeature );
622  }
623  return result;
624 }
625 
626 QgsFeature QgsVectorLayerUtils::duplicateFeature( QgsVectorLayer *layer, const QgsFeature &feature, QgsProject *project, QgsDuplicateFeatureContext &duplicateFeatureContext, const int maxDepth, int depth, QList<QgsVectorLayer *> referencedLayersBranch )
627 {
628  if ( !layer )
629  return QgsFeature();
630 
631  if ( !layer->isEditable() )
632  return QgsFeature();
633 
634  //get context from layer
636  context.setFeature( feature );
637 
638  QgsFeature newFeature = createFeature( layer, feature.geometry(), feature.attributes().toMap(), &context );
639  layer->addFeature( newFeature );
640 
641  const QList<QgsRelation> relations = project->relationManager()->referencedRelations( layer );
642 
643  const int effectiveMaxDepth = maxDepth > 0 ? maxDepth : 100;
644 
645  for ( const QgsRelation &relation : relations )
646  {
647  //check if composition (and not association)
648  if ( relation.strength() == QgsRelation::Composition && !referencedLayersBranch.contains( relation.referencedLayer() ) && depth < effectiveMaxDepth )
649  {
650  depth++;
651  referencedLayersBranch << layer;
652 
653  //get features connected over this relation
654  QgsFeatureIterator relatedFeaturesIt = relation.getRelatedFeatures( feature );
655  QgsFeatureIds childFeatureIds;
656  QgsFeature childFeature;
657  while ( relatedFeaturesIt.nextFeature( childFeature ) )
658  {
659  //set childlayer editable
660  relation.referencingLayer()->startEditing();
661  //change the fk of the child to the id of the new parent
662  const auto pairs = relation.fieldPairs();
663  for ( const QgsRelation::FieldPair &fieldPair : pairs )
664  {
665  childFeature.setAttribute( fieldPair.first, newFeature.attribute( fieldPair.second ) );
666  }
667  //call the function for the child
668  childFeatureIds.insert( duplicateFeature( relation.referencingLayer(), childFeature, project, duplicateFeatureContext, maxDepth, depth, referencedLayersBranch ).id() );
669  }
670 
671  //store for feedback
672  duplicateFeatureContext.setDuplicatedFeatures( relation.referencingLayer(), childFeatureIds );
673  }
674  }
675 
676 
677  return newFeature;
678 }
679 
680 std::unique_ptr<QgsVectorLayerFeatureSource> QgsVectorLayerUtils::getFeatureSource( QPointer<QgsVectorLayer> layer, QgsFeedback *feedback )
681 {
682  std::unique_ptr<QgsVectorLayerFeatureSource> featureSource;
683 
684  auto getFeatureSource = [ layer, &featureSource, feedback ]
685  {
686 #if QT_VERSION >= QT_VERSION_CHECK( 5, 10, 0 )
687  Q_ASSERT( QThread::currentThread() == qApp->thread() || feedback );
688 #else
689  Q_UNUSED( feedback )
690 #endif
691  QgsVectorLayer *lyr = layer.data();
692 
693  if ( lyr )
694  {
695  featureSource.reset( new QgsVectorLayerFeatureSource( lyr ) );
696  }
697  };
698 
700 
701  return featureSource;
702 }
703 
705 {
706  if ( !feature.fields().isEmpty() )
707  {
708  QgsAttributes attributes;
709  attributes.reserve( fields.size() );
710  // feature has a field mapping, so we can match attributes to field names
711  for ( const QgsField &field : fields )
712  {
713  int index = feature.fields().lookupField( field.name() );
714  attributes.append( index >= 0 ? feature.attribute( index ) : QVariant( field.type() ) );
715  }
716  feature.setAttributes( attributes );
717  }
718  else
719  {
720  // no field name mapping in feature, just use order
721  const int lengthDiff = feature.attributes().count() - fields.count();
722  if ( lengthDiff > 0 )
723  {
724  // truncate extra attributes
725  QgsAttributes attributes = feature.attributes().mid( 0, fields.count() );
726  feature.setAttributes( attributes );
727  }
728  else if ( lengthDiff < 0 )
729  {
730  // add missing null attributes
731  QgsAttributes attributes = feature.attributes();
732  attributes.reserve( fields.count() );
733  for ( int i = feature.attributes().count(); i < fields.count(); ++i )
734  {
735  attributes.append( QVariant( fields.at( i ).type() ) );
736  }
737  feature.setAttributes( attributes );
738  }
739  }
740  feature.setFields( fields );
741 }
742 
743 QgsFeatureList QgsVectorLayerUtils::makeFeatureCompatible( const QgsFeature &feature, const QgsVectorLayer *layer, QgsFeatureSink::SinkFlags sinkFlags )
744 {
745  QgsWkbTypes::Type inputWkbType( layer->wkbType( ) );
746  QgsFeatureList resultFeatures;
747  QgsFeature newF( feature );
748  // Fix attributes
750 
751  if ( sinkFlags & QgsFeatureSink::RegeneratePrimaryKey )
752  {
753  // drop incoming primary key values, let them be regenerated
754  const QgsAttributeList pkIndexes = layer->dataProvider()->pkAttributeIndexes();
755  for ( int index : pkIndexes )
756  {
757  if ( index >= 0 )
758  newF.setAttribute( index, QVariant() );
759  }
760  }
761 
762  // Does geometry need transformations?
764  bool newFHasGeom = newFGeomType !=
765  QgsWkbTypes::GeometryType::UnknownGeometry &&
766  newFGeomType != QgsWkbTypes::GeometryType::NullGeometry;
767  bool layerHasGeom = inputWkbType !=
768  QgsWkbTypes::Type::NoGeometry &&
769  inputWkbType != QgsWkbTypes::Type::Unknown;
770  // Drop geometry if layer is geometry-less
771  if ( ( newFHasGeom && !layerHasGeom ) || !newFHasGeom )
772  {
773  QgsFeature _f = QgsFeature( layer->fields() );
774  _f.setAttributes( newF.attributes() );
775  resultFeatures.append( _f );
776  }
777  else
778  {
779  // Geometry need fixing?
780  const QVector< QgsGeometry > geometries = newF.geometry().coerceToType( inputWkbType );
781 
782  if ( geometries.count() != 1 )
783  {
784  QgsAttributeMap attrMap;
785  for ( int j = 0; j < newF.fields().count(); j++ )
786  {
787  attrMap[j] = newF.attribute( j );
788  }
789  resultFeatures.reserve( geometries.size() );
790  for ( const QgsGeometry &geometry : geometries )
791  {
792  QgsFeature _f( createFeature( layer, geometry, attrMap ) );
793  resultFeatures.append( _f );
794  }
795  }
796  else
797  {
798  newF.setGeometry( geometries.at( 0 ) );
799  resultFeatures.append( newF );
800  }
801  }
802  return resultFeatures;
803 }
804 
805 QgsFeatureList QgsVectorLayerUtils::makeFeaturesCompatible( const QgsFeatureList &features, const QgsVectorLayer *layer, QgsFeatureSink::SinkFlags sinkFlags )
806 {
807  QgsFeatureList resultFeatures;
808  for ( const QgsFeature &f : features )
809  {
810  const QgsFeatureList features( makeFeatureCompatible( f, layer, sinkFlags ) );
811  for ( const auto &_f : features )
812  {
813  resultFeatures.append( _f );
814  }
815  }
816  return resultFeatures;
817 }
818 
820 {
821  QList<QgsVectorLayer *> layers;
822  QMap<QgsVectorLayer *, QgsFeatureIds>::const_iterator i;
823  for ( i = mDuplicatedFeatures.begin(); i != mDuplicatedFeatures.end(); ++i )
824  layers.append( i.key() );
825  return layers;
826 }
827 
829 {
830  return mDuplicatedFeatures[layer];
831 }
832 
833 void QgsVectorLayerUtils::QgsDuplicateFeatureContext::setDuplicatedFeatures( QgsVectorLayer *layer, const QgsFeatureIds &ids )
834 {
835  if ( mDuplicatedFeatures.contains( layer ) )
836  mDuplicatedFeatures[layer] += ids;
837  else
838  mDuplicatedFeatures.insert( layer, ids );
839 }
840 /*
841 QMap<QgsVectorLayer *, QgsFeatureIds> QgsVectorLayerUtils::QgsDuplicateFeatureContext::duplicateFeatureContext() const
842 {
843  return mDuplicatedFeatures;
844 }
845 */
846 
848  mGeometry( geometry ),
849  mAttributes( attributes )
850 {}
851 
853 {
854  return mGeometry;
855 }
856 
858 {
859  return mAttributes;
860 }
861 
862 bool _fieldIsEditable( const QgsVectorLayer *layer, int fieldIndex, const QgsFeature &feature )
863 {
864  return layer->isEditable() &&
865  !layer->editFormConfig().readOnly( fieldIndex ) &&
866  layer->dataProvider() &&
868  !layer->fields().at( fieldIndex ).isReadOnly();
869 }
870 
871 bool QgsVectorLayerUtils::fieldIsEditable( const QgsVectorLayer *layer, int fieldIndex, const QgsFeature &feature )
872 {
873  if ( layer->fields().fieldOrigin( fieldIndex ) == QgsFields::OriginJoin )
874  {
875  int srcFieldIndex;
876  const QgsVectorLayerJoinInfo *info = layer->joinBuffer()->joinForFieldIndex( fieldIndex, layer->fields(), srcFieldIndex );
877 
878  if ( !info || !info->isEditable() )
879  return false;
880 
881  // check that joined feature exist, else it is not editable
882  if ( !info->hasUpsertOnEdit() )
883  {
884  const QgsFeature joinedFeature = layer->joinBuffer()->joinedFeatureOf( info, feature );
885  if ( !joinedFeature.isValid() )
886  return false;
887  }
888 
889  return _fieldIsEditable( info->joinLayer(), srcFieldIndex, feature );
890  }
891  else
892  return _fieldIsEditable( layer, fieldIndex, feature );
893 }
894 
895 QHash<QString, QHash<QString, QSet<QgsSymbolLayerId>>> QgsVectorLayerUtils::labelMasks( const QgsVectorLayer *layer )
896 {
897  class LabelMasksVisitor : public QgsStyleEntityVisitorInterface
898  {
899  public:
900  bool visitEnter( const QgsStyleEntityVisitorInterface::Node &node ) override
901  {
903  {
904  currentRule = node.identifier;
905  return true;
906  }
907  return false;
908  }
909  bool visit( const QgsStyleEntityVisitorInterface::StyleLeaf &leaf ) override
910  {
911  if ( leaf.entity && leaf.entity->type() == QgsStyle::LabelSettingsEntity )
912  {
913  auto labelSettingsEntity = static_cast<const QgsStyleLabelSettingsEntity *>( leaf.entity );
914  if ( labelSettingsEntity->settings().format().mask().enabled() )
915  {
916  for ( const auto &r : labelSettingsEntity->settings().format().mask().maskedSymbolLayers() )
917  {
918  masks[currentRule][r.layerId()].insert( r.symbolLayerId() );
919  }
920  }
921  }
922  return true;
923  }
924 
925  QHash<QString, QHash<QString, QSet<QgsSymbolLayerId>>> masks;
926  // Current label rule, empty string for a simple labeling
927  QString currentRule;
928  };
929 
930  if ( ! layer->labeling() )
931  return {};
932 
933  LabelMasksVisitor visitor;
934  layer->labeling()->accept( &visitor );
935  return std::move( visitor.masks );
936 }
937 
938 QHash<QString, QSet<QgsSymbolLayerId>> QgsVectorLayerUtils::symbolLayerMasks( const QgsVectorLayer *layer )
939 {
940  if ( ! layer->renderer() )
941  return {};
942 
944  {
945  public:
946  bool visitEnter( const QgsStyleEntityVisitorInterface::Node &node ) override
947  {
949  }
950 
951  void visitSymbol( const QgsSymbol *symbol )
952  {
953  for ( int idx = 0; idx < symbol->symbolLayerCount(); idx++ )
954  {
955  const QgsSymbolLayer *sl = symbol->symbolLayer( idx );
956  for ( const auto &mask : sl->masks() )
957  {
958  masks[mask.layerId()].insert( mask.symbolLayerId() );
959  }
960  // recurse over sub symbols
961  const QgsSymbol *subSymbol = const_cast<QgsSymbolLayer *>( sl )->subSymbol();
962  if ( subSymbol )
963  visitSymbol( subSymbol );
964  }
965  }
966 
967  bool visit( const QgsStyleEntityVisitorInterface::StyleLeaf &leaf ) override
968  {
969  if ( leaf.entity && leaf.entity->type() == QgsStyle::SymbolEntity )
970  {
971  auto symbolEntity = static_cast<const QgsStyleSymbolEntity *>( leaf.entity );
972  if ( symbolEntity->symbol() )
973  visitSymbol( symbolEntity->symbol() );
974  }
975  return true;
976  }
977  QHash<QString, QSet<QgsSymbolLayerId>> masks;
978  };
979 
980  SymbolLayerVisitor visitor;
981  layer->renderer()->accept( &visitor );
982  return visitor.masks;
983 }
984 
986 {
988 
989  QgsExpression exp( layer->displayExpression() );
990  context.setFeature( feature );
991  exp.prepare( &context );
992  QString displayString = exp.evaluate( &context ).toString();
993 
994  return displayString;
995 }
996 
997 bool QgsVectorLayerUtils::impactsCascadeFeatures( const QgsVectorLayer *layer, const QgsFeatureIds &fids, const QgsProject *project, QgsDuplicateFeatureContext &context, CascadedFeatureFlags flags )
998 {
999  if ( !layer )
1000  return false;
1001 
1002  const QList<QgsRelation> relations = project->relationManager()->referencedRelations( layer );
1003  for ( const QgsRelation &relation : relations )
1004  {
1005  if ( relation.strength() == QgsRelation::Composition )
1006  {
1007  QgsFeatureIds childFeatureIds;
1008 
1009  const auto constFids = fids;
1010  for ( const QgsFeatureId fid : constFids )
1011  {
1012  //get features connected over this relation
1013  QgsFeatureIterator relatedFeaturesIt = relation.getRelatedFeatures( layer->getFeature( fid ) );
1014  QgsFeature childFeature;
1015  while ( relatedFeaturesIt.nextFeature( childFeature ) )
1016  {
1017  childFeatureIds.insert( childFeature.id() );
1018  }
1019  }
1020 
1021  if ( childFeatureIds.count() > 0 )
1022  {
1023  if ( context.layers().contains( relation.referencingLayer() ) )
1024  {
1025  QgsFeatureIds handledFeatureIds = context.duplicatedFeatures( relation.referencingLayer() );
1026  // add feature ids
1027  handledFeatureIds.unite( childFeatureIds );
1028  context.setDuplicatedFeatures( relation.referencingLayer(), handledFeatureIds );
1029  }
1030  else
1031  {
1032  // add layer and feature id
1033  context.setDuplicatedFeatures( relation.referencingLayer(), childFeatureIds );
1034  }
1035  }
1036  }
1037  }
1038 
1039  if ( layer->joinBuffer()->containsJoins() )
1040  {
1041  const QgsVectorJoinList joins = layer->joinBuffer()->vectorJoins();
1042  for ( const QgsVectorLayerJoinInfo &info : joins )
1043  {
1044  if ( qobject_cast< QgsAuxiliaryLayer * >( info.joinLayer() ) && flags & IgnoreAuxiliaryLayers )
1045  continue;
1046 
1047  if ( info.isEditable() && info.hasCascadedDelete() )
1048  {
1049  QgsFeatureIds joinFeatureIds;
1050  const auto constFids = fids;
1051  for ( const QgsFeatureId &fid : constFids )
1052  {
1053  const QgsFeature joinFeature = layer->joinBuffer()->joinedFeatureOf( &info, layer->getFeature( fid ) );
1054  if ( joinFeature.isValid() )
1055  joinFeatureIds.insert( joinFeature.id() );
1056  }
1057 
1058  if ( joinFeatureIds.count() > 0 )
1059  {
1060  if ( context.layers().contains( info.joinLayer() ) )
1061  {
1062  QgsFeatureIds handledFeatureIds = context.duplicatedFeatures( info.joinLayer() );
1063  // add feature ids
1064  handledFeatureIds.unite( joinFeatureIds );
1065  context.setDuplicatedFeatures( info.joinLayer(), handledFeatureIds );
1066  }
1067  else
1068  {
1069  // add layer and feature id
1070  context.setDuplicatedFeatures( info.joinLayer(), joinFeatureIds );
1071  }
1072  }
1073  }
1074  }
1075  }
1076 
1077  return context.layers().count();
1078 }
int lookupField(const QString &fieldName) const
Looks up field&#39;s index from the field name.
Definition: qgsfields.cpp:344
bool _fieldIsEditable(const QgsVectorLayer *layer, int fieldIndex, const QgsFeature &feature)
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:185
Class for parsing and evaluation of expressions (formerly called "search strings").
QgsFeatureId id
Definition: qgsfeature.h:64
Wrapper for iterator of features from vector data provider or vector layer.
A symbol entity for QgsStyle databases.
Definition: qgsstyle.h:1200
bool containsJoins() const
Quick way to test if there is any join at all.
Field comes from a joined layer (originIndex / 1000 = index of the join, originIndex % 1000 = index w...
Definition: qgsfields.h:52
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeatureid.h:37
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.
int size() const
Returns number of items.
Definition: qgsfields.cpp:138
FieldOrigin fieldOrigin(int fieldIdx) const
Gets field&#39;s origin (value from an enumeration)
Definition: qgsfields.cpp:189
virtual QgsVectorDataProvider::Capabilities capabilities() const
Returns flags containing the supported capabilities.
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes)
void setFields(const QgsFields &fields, bool initAttributes=false)
Assign a field map with the feature to allow attribute access by attribute name.
Definition: qgsfeature.cpp:164
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:59
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:64
bool isValid() const
Returns if this default value should be applied.
static std::unique_ptr< QgsVectorLayerFeatureSource > getFeatureSource(QPointer< QgsVectorLayer > layer, QgsFeedback *feedback=nullptr)
Gets the feature source from a QgsVectorLayer pointer.
The QgsDefaultValue class provides a container for managing client side default values for fields...
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.
Q_INVOKABLE QgsWkbTypes::Type wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:583
ConstraintOrigin
Origin of constraints.
Generic visitor that collects symbol layers of a vector layer&#39;s renderer and call a callback function...
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.
QgsFeature getFeature(QgsFeatureId fid) const
Queries the layer for the feature with the given id.
static QgsFeatureList createFeatures(const QgsVectorLayer *layer, const QgsFeaturesDataList &featuresData, QgsExpressionContext *context=nullptr)
Creates a set of new features ready for insertion into a layer.
static QgsFeatureList makeFeaturesCompatible(const QgsFeatureList &features, const QgsVectorLayer *layer, QgsFeatureSink::SinkFlags sinkFlags=QgsFeatureSink::SinkFlags())
Converts input features to be compatible with the given layer.
QVariant evaluate()
Evaluate the feature and return the result.
virtual QgsAttributeList pkAttributeIndexes() const
Returns list of indexes of fields that make up the primary key.
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features ...
Definition: qgsfeatureid.h:28
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
Container of fields for a vector layer.
Definition: qgsfields.h:44
QVector< QgsGeometry > coerceToType(QgsWkbTypes::Type type) const
Attempts to coerce this geometry into the specified destination type.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:123
void setAttributes(const QgsAttributes &attrs)
Sets the feature&#39;s attributes.
Definition: qgsfeature.cpp:129
bool setAttribute(int field, const QVariant &attr)
Set an attribute&#39;s value by field index.
Definition: qgsfeature.cpp:213
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.
int symbolLayerCount() const
Returns the total number of symbol layers contained in the symbol.
Definition: qgssymbol.h:199
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:51
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
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...
An interface for classes which can visit style entity (e.g.
QgsFields fields
Definition: qgsfeature.h:66
static QString getFeatureDisplayString(const QgsVectorLayer *layer, const QgsFeature &feature)
static QHash< QString, QSet< QgsSymbolLayerId > > symbolLayerMasks(const QgsVectorLayer *)
Returns all masks that may be defined on symbol layers for a given vector layer.
int count() const
Returns number of items.
Definition: qgsfields.cpp:133
static QgsFeatureIterator getValuesIterator(const QgsVectorLayer *layer, const QString &fieldOrExpression, bool &ok, bool selectedOnly)
Create a feature iterator for a specified field name or expression.
QList< QgsRelation > referencedRelations(const QgsVectorLayer *layer=nullptr) const
Gets all relations where this layer is the referenced part (i.e.
Constraint was set at data provider.
Field has an expression constraint set. See constraintExpression().
static QgsFeatureList makeFeatureCompatible(const QgsFeature &feature, const QgsVectorLayer *layer, QgsFeatureSink::SinkFlags sinkFlags=QgsFeatureSink::SinkFlags())
Converts input feature to be compatible with the given layer.
This flag indicates, that a primary key field cannot be guaranteed to be unique and the sink should i...
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
Definition: qgsfields.cpp:163
int fieldOriginIndex(int fieldIdx) const
Gets field&#39;s origin index (its meaning is specific to each type of origin)
Definition: qgsfields.cpp:197
Base class for feedback objects to be used for cancellation of something running in a worker thread...
Definition: qgsfeedback.h:43
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...
bool isEditable() const FINAL
Returns true if the provider is in editing mode.
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:69
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.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
Defines a relation between matching fields of the two involved tables of a relation.
Definition: qgsrelation.h:74
QgsVectorLayer * joinLayer() const
Returns joined layer (may be nullptr if the reference was set by layer ID and not resolved yet) ...
static void matchAttributesToFields(QgsFeature &feature, const QgsFields &fields)
Matches the attributes in feature to the specified fields.
static QVariant createUniqueValueFromCache(const QgsVectorLayer *layer, int fieldIndex, const QSet< QVariant > &existingValues, const QVariant &seed=QVariant())
Returns a new attribute value for the specified field index which is guaranteed to be unique within r...
virtual QgsSymbolLayerReferenceList masks() const
Returns masks defined by this symbol layer.
QgsFeatureIterator getSelectedFeatures(QgsFeatureRequest request=QgsFeatureRequest()) const
Returns an iterator of the selected features.
QgsFeatureRequest & setNoAttributes()
Set that no attributes will be fetched.
QgsFeatureData(const QgsGeometry &geometry=QgsGeometry(), const QgsAttributeMap &attributes=QgsAttributeMap())
Constructs a new QgsFeatureData with given geometry and attributes.
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:204
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QgsAttributeMap attributes() const
Returns attributes.
static QgsFeature createFeature(const QgsVectorLayer *layer, const QgsGeometry &geometry=QgsGeometry(), const QgsAttributeMap &attributes=QgsAttributeMap(), QgsExpressionContext *context=nullptr)
Creates a new feature ready for insertion into a layer.
Encapsulate geometry and attributes for new features, to be passed to createFeatures.
virtual bool accept(QgsStyleEntityVisitorInterface *visitor) const
Accepts the specified symbology visitor, causing it to visit all symbols associated with the labeling...
Defines left outer join from our vector layer to some other vector layer.
QMap< int, QVariant > QgsAttributeMap
Definition: qgsattributes.h:38
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...
Contains information relating to a node (i.e.
QString subsetString
QgsStyleEntityVisitorInterface::NodeType type
Node type.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts, annotations, canvases, etc.
Definition: qgsproject.h:94
QgsAttributeMap toMap() const
Returns a QgsAttributeMap of the attribute values.
QgsFeatureRenderer * renderer()
Returns renderer.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer&#39;s project and layer.
const QgsVectorJoinList & vectorJoins() const
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:49
const QgsAbstractVectorLayerLabeling * labeling() const
Access to const labeling configuration.
QgsRelationManager relationManager
Definition: qgsproject.h:105
QgsEditFormConfig editFormConfig
QgsExpressionContext createExpressionContext() const FINAL
This method needs to be reimplemented in all classes which implement this interface and return an exp...
static bool runOnMainThread(const Func &func, QgsFeedback *feedback=nullptr)
Guarantees that func is executed on the main thread.
QgsSymbolLayer * symbolLayer(int layer)
Returns the symbol layer at the specified index.
Definition: qgssymbol.cpp:393
QString displayExpression
QgsVectorLayerJoinBuffer * joinBuffer()
Returns the join buffer object.
Partial snapshot of vector layer&#39;s state (only the members necessary for access to features) ...
Rule based symbology or label child rule.
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...
virtual bool accept(QgsStyleEntityVisitorInterface *visitor) const
Accepts the specified symbology visitor, causing it to visit all symbols associated with the renderer...
QgsGeometry geometry() const
Returns geometry.
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Definition: qgswkbtypes.h:140
#define FID_IS_NEW(fid)
Definition: qgsfeatureid.h:31
void setValid(bool validity)
Sets the validity of the feature.
Definition: qgsfeature.cpp:190
QgsDefaultValue defaultValueDefinition(int index) const
Returns the definition of the expression used when calculating the default value for a field...
virtual QgsStyle::StyleEntity type() const =0
Returns the type of style entity.
QgsFieldConstraints constraints
Definition: qgsfield.h:62
static QHash< QString, QHash< QString, QSet< QgsSymbolLayerId > > > labelMasks(const QgsVectorLayer *)
Returns masks defined in labeling options of a layer.
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:53
QSet< QVariant > uniqueValues(int fieldIndex, int limit=-1) const FINAL
Calculates a list of unique values contained within an attribute in the layer.
ConstraintStrength
Strength of constraints.
QgsFeatureIds duplicatedFeatures(QgsVectorLayer *layer) const
Returns the duplicated features in the given layer.
A label settings entity for QgsStyle databases.
Definition: qgsstyle.h:1293
static bool impactsCascadeFeatures(const QgsVectorLayer *layer, const QgsFeatureIds &fids, const QgsProject *project, QgsDuplicateFeatureContext &context, QgsVectorLayerUtils::CascadedFeatureFlags flags=QgsVectorLayerUtils::CascadedFeatureFlags())
void setGeometry(const QgsGeometry &geometry)
Set the feature&#39;s geometry.
Definition: qgsfeature.cpp:139
const QgsVectorLayerJoinInfo * joinForFieldIndex(int index, const QgsFields &fields, int &sourceFieldIndex) const
Finds the vector join for a layer field index.
QgsFeatureRequest & setLimit(long limit)
Set the maximum number of features to request.
bool isEmpty() const
Checks whether the container is empty.
Definition: qgsfields.cpp:128
QgsFeature joinedFeatureOf(const QgsVectorLayerJoinInfo *info, const QgsFeature &feature) const
Returns the joined feature corresponding to the feature.
virtual bool setSubsetString(const QString &subset)
Sets the string (typically sql) used to define a subset of the layer.
bool convertCompatible(QVariant &v, QString *errorMessage=nullptr) const
Converts the provided variant to a compatible format.
Definition: qgsfield.cpp:371
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
bool isNumeric
Definition: qgsfield.h:53
ConstraintOrigin constraintOrigin(Constraint constraint) const
Returns the origin of a field constraint, or ConstraintOriginNotSet if the constraint is not present ...
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) FINAL
Adds a single feature to the sink.
void appendScopes(const QList< QgsExpressionContextScope *> &scopes)
Appends a list of scopes to the end of the context.
QgsGeometry geometry
Definition: qgsfeature.h:67
bool readOnly(int idx) const
This returns true if the field is manually set to read only or if the field does not support editing ...
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer&#39;s data provider, it may be nullptr.
QList< int > QgsAttributeList
Definition: qgsfield.h:26
bool isEditable() const
Returns whether joined fields may be edited through the form of the target layer. ...
QList< QgsVectorLayerJoinInfo > QgsVectorJoinList
bool hasUpsertOnEdit() const
Returns whether a feature created on the target layer has to impact the joined layer by creating a ne...
bool nextFeature(QgsFeature &f)
const QgsStyleEntityInterface * entity
Reference to style entity being visited.
static QString quotedValue(const QVariant &value)
Returns a string representation of a literal value, including appropriate quotations where required...
static QgsFeature duplicateFeature(QgsVectorLayer *layer, const QgsFeature &feature, QgsProject *project, QgsDuplicateFeatureContext &duplicateFeatureContext, const int maxDepth=0, int depth=0, QList< QgsVectorLayer *> referencedLayersBranch=QList< QgsVectorLayer *>())
Duplicates a feature and it&#39;s children (one level deep).
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:57
QVariant maximumValue(int index) const FINAL
Returns the maximum value for an attribute column or an invalid variant in case of error...
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:264
static bool fieldIsEditable(const QgsVectorLayer *layer, int fieldIndex, const QgsFeature &feature)
Allows modification of attribute values.
Contains information relating to the style entity currently being visited.
const QgsField & field
Definition: qgsfield.h:471
QVariant::Type type
Definition: qgsfield.h:57
static GeometryType geometryType(Type type) SIP_HOLDGIL
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
Definition: qgswkbtypes.h:938
bool isReadOnly
Definition: qgsfield.h:64
QgsAttributes attributes
Definition: qgsfeature.h:65
Fix relation, related elements are part of the parent and a parent copy will copy any children or del...
Definition: qgsrelation.h:60
QList< QgsVectorLayerUtils::QgsFeatureData > QgsFeaturesDataList
Alias for list of QgsFeatureData.
QgsVectorLayer * clone() const override
Returns a new instance equivalent to this one.
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets 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.
QString identifier
A string identifying the node.
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...