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