QGIS API Documentation  3.12.1-BucureČ™ti (121cc00ff0)
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 
44 QgsFeatureIterator QgsVectorLayerUtils::getValuesIterator( const QgsVectorLayer *layer, const QString &fieldOrExpression, bool &ok, bool selectedOnly )
45 {
46  std::unique_ptr<QgsExpression> expression;
47  QgsExpressionContext context;
48 
49  int attrNum = layer->fields().lookupField( fieldOrExpression );
50  if ( attrNum == -1 )
51  {
52  // try to use expression
53  expression.reset( new QgsExpression( fieldOrExpression ) );
55 
56  if ( expression->hasParserError() || !expression->prepare( &context ) )
57  {
58  ok = false;
59  return QgsFeatureIterator();
60  }
61  }
62 
63  QSet<QString> lst;
64  if ( !expression )
65  lst.insert( fieldOrExpression );
66  else
67  lst = expression->referencedColumns();
68 
70  .setFlags( ( expression && expression->needsGeometry() ) ?
73  .setSubsetOfAttributes( lst, layer->fields() );
74 
75  ok = true;
76  if ( !selectedOnly )
77  {
78  return layer->getFeatures( request );
79  }
80  else
81  {
82  return layer->getSelectedFeatures( request );
83  }
84 }
85 
86 QList<QVariant> QgsVectorLayerUtils::getValues( const QgsVectorLayer *layer, const QString &fieldOrExpression, bool &ok, bool selectedOnly, QgsFeedback *feedback )
87 {
88  QList<QVariant> values;
89  QgsFeatureIterator fit = getValuesIterator( layer, fieldOrExpression, ok, selectedOnly );
90  if ( ok )
91  {
92  std::unique_ptr<QgsExpression> expression;
93  QgsExpressionContext context;
94 
95  int attrNum = layer->fields().lookupField( fieldOrExpression );
96  if ( attrNum == -1 )
97  {
98  // use expression, already validated in the getValuesIterator() function
99  expression.reset( new QgsExpression( fieldOrExpression ) );
101  }
102 
103  QgsFeature f;
104  while ( fit.nextFeature( f ) )
105  {
106  if ( expression )
107  {
108  context.setFeature( f );
109  QVariant v = expression->evaluate( &context );
110  values << v;
111  }
112  else
113  {
114  values << f.attribute( attrNum );
115  }
116  if ( feedback && feedback->isCanceled() )
117  {
118  ok = false;
119  return values;
120  }
121  }
122  }
123  return values;
124 }
125 
126 QList<double> QgsVectorLayerUtils::getDoubleValues( const QgsVectorLayer *layer, const QString &fieldOrExpression, bool &ok, bool selectedOnly, int *nullCount, QgsFeedback *feedback )
127 {
128  QList<double> values;
129 
130  if ( nullCount )
131  *nullCount = 0;
132 
133  QList<QVariant> variantValues = getValues( layer, fieldOrExpression, ok, selectedOnly, feedback );
134  if ( !ok )
135  return values;
136 
137  bool convertOk;
138  const auto constVariantValues = variantValues;
139  for ( const QVariant &value : constVariantValues )
140  {
141  double val = value.toDouble( &convertOk );
142  if ( convertOk )
143  values << val;
144  else if ( value.isNull() )
145  {
146  if ( nullCount )
147  *nullCount += 1;
148  }
149  if ( feedback && feedback->isCanceled() )
150  {
151  ok = false;
152  return values;
153  }
154  }
155  return values;
156 }
157 
158 bool QgsVectorLayerUtils::valueExists( const QgsVectorLayer *layer, int fieldIndex, const QVariant &value, const QgsFeatureIds &ignoreIds )
159 {
160  if ( !layer )
161  return false;
162 
163  QgsFields fields = layer->fields();
164 
165  if ( fieldIndex < 0 || fieldIndex >= fields.count() )
166  return false;
167 
168  QString fieldName = fields.at( fieldIndex ).name();
169 
170  // build up an optimised feature request
171  QgsFeatureRequest request;
172  request.setNoAttributes();
174 
175  // at most we need to check ignoreIds.size() + 1 - the feature not in ignoreIds is the one we're interested in
176  int limit = ignoreIds.size() + 1;
177  request.setLimit( limit );
178 
179  request.setFilterExpression( QStringLiteral( "%1=%2" ).arg( QgsExpression::quotedColumnRef( fieldName ),
180  QgsExpression::quotedValue( value ) ) );
181 
182  QgsFeature feat;
183  QgsFeatureIterator it = layer->getFeatures( request );
184  while ( it.nextFeature( feat ) )
185  {
186  if ( ignoreIds.contains( feat.id() ) )
187  continue;
188 
189  return true;
190  }
191 
192  return false;
193 }
194 
195 QVariant QgsVectorLayerUtils::createUniqueValue( const QgsVectorLayer *layer, int fieldIndex, const QVariant &seed )
196 {
197  if ( !layer )
198  return QVariant();
199 
200  QgsFields fields = layer->fields();
201 
202  if ( fieldIndex < 0 || fieldIndex >= fields.count() )
203  return QVariant();
204 
205  QgsField field = fields.at( fieldIndex );
206 
207  if ( field.isNumeric() )
208  {
209  QVariant maxVal = layer->maximumValue( fieldIndex );
210  QVariant newVar( maxVal.toLongLong() + 1 );
211  if ( field.convertCompatible( newVar ) )
212  return newVar;
213  else
214  return QVariant();
215  }
216  else
217  {
218  switch ( field.type() )
219  {
220  case QVariant::String:
221  {
222  QString base;
223  if ( seed.isValid() )
224  base = seed.toString();
225 
226  if ( !base.isEmpty() )
227  {
228  // strip any existing _1, _2 from the seed
229  QRegularExpression rx( QStringLiteral( "(.*)_\\d+" ) );
230  QRegularExpressionMatch match = rx.match( base );
231  if ( match.hasMatch() )
232  {
233  base = match.captured( 1 );
234  }
235  }
236  else
237  {
238  // no base seed - fetch first value from layer
239  QgsFeatureRequest req;
240  req.setLimit( 1 );
241  req.setSubsetOfAttributes( QgsAttributeList() << fieldIndex );
243  QgsFeature f;
244  layer->getFeatures( req ).nextFeature( f );
245  base = f.attribute( fieldIndex ).toString();
246  }
247 
248  // try variants like base_1, base_2, etc until a new value found
249  QStringList vals = layer->uniqueStringsMatching( fieldIndex, base );
250 
251  // might already be unique
252  if ( !base.isEmpty() && !vals.contains( base ) )
253  return base;
254 
255  for ( int i = 1; i < 10000; ++i )
256  {
257  QString testVal = base + '_' + QString::number( i );
258  if ( !vals.contains( testVal ) )
259  return testVal;
260  }
261 
262  // failed
263  return QVariant();
264  }
265 
266  default:
267  // todo other types - dates? times?
268  break;
269  }
270  }
271 
272  return QVariant();
273 }
274 
275 QVariant QgsVectorLayerUtils::createUniqueValueFromCache( const QgsVectorLayer *layer, int fieldIndex, const QSet<QVariant> &existingValues, const QVariant &seed )
276 {
277  if ( !layer )
278  return QVariant();
279 
280  QgsFields fields = layer->fields();
281 
282  if ( fieldIndex < 0 || fieldIndex >= fields.count() )
283  return QVariant();
284 
285  QgsField field = fields.at( fieldIndex );
286 
287  if ( field.isNumeric() )
288  {
289  QVariant maxVal = existingValues.isEmpty() ? 0 : *std::max_element( existingValues.begin(), existingValues.end() );
290  QVariant newVar( maxVal.toLongLong() + 1 );
291  if ( field.convertCompatible( newVar ) )
292  return newVar;
293  else
294  return QVariant();
295  }
296  else
297  {
298  switch ( field.type() )
299  {
300  case QVariant::String:
301  {
302  QString base;
303  if ( seed.isValid() )
304  base = seed.toString();
305 
306  if ( !base.isEmpty() )
307  {
308  // strip any existing _1, _2 from the seed
309  QRegularExpression rx( QStringLiteral( "(.*)_\\d+" ) );
310  QRegularExpressionMatch match = rx.match( base );
311  if ( match.hasMatch() )
312  {
313  base = match.captured( 1 );
314  }
315  }
316  else
317  {
318  // no base seed - fetch first value from layer
319  QgsFeatureRequest req;
320  base = existingValues.isEmpty() ? QString() : existingValues.values().first().toString();
321  }
322 
323  // try variants like base_1, base_2, etc until a new value found
324  QStringList vals;
325  for ( const auto &v : qgis::as_const( existingValues ) )
326  {
327  if ( v.toString().startsWith( base ) )
328  vals.push_back( v.toString() );
329  }
330 
331  // might already be unique
332  if ( !base.isEmpty() && !vals.contains( base ) )
333  return base;
334 
335  for ( int i = 1; i < 10000; ++i )
336  {
337  QString testVal = base + '_' + QString::number( i );
338  if ( !vals.contains( testVal ) )
339  return testVal;
340  }
341 
342  // failed
343  return QVariant();
344  }
345 
346  default:
347  // todo other types - dates? times?
348  break;
349  }
350  }
351 
352  return QVariant();
353 
354 }
355 
356 bool QgsVectorLayerUtils::validateAttribute( const QgsVectorLayer *layer, const QgsFeature &feature, int attributeIndex, QStringList &errors,
358 {
359  if ( !layer )
360  return false;
361 
362  if ( attributeIndex < 0 || attributeIndex >= layer->fields().count() )
363  return false;
364 
365  QgsFields fields = layer->fields();
366  QgsField field = fields.at( attributeIndex );
367  QVariant value = feature.attribute( attributeIndex );
368  bool valid = true;
369  errors.clear();
370 
371  QgsFieldConstraints constraints = field.constraints();
372 
373  if ( constraints.constraints() & QgsFieldConstraints::ConstraintExpression && !constraints.constraintExpression().isEmpty()
376  {
378  context.setFeature( feature );
379 
380  QgsExpression expr( constraints.constraintExpression() );
381 
382  valid = expr.evaluate( &context ).toBool();
383 
384  if ( expr.hasParserError() )
385  {
386  errors << QObject::tr( "parser error: %1" ).arg( expr.parserErrorString() );
387  }
388  else if ( expr.hasEvalError() )
389  {
390  errors << QObject::tr( "evaluation error: %1" ).arg( expr.evalErrorString() );
391  }
392  else if ( !valid )
393  {
394  errors << QObject::tr( "%1 check failed" ).arg( constraints.constraintDescription() );
395  }
396  }
397 
401  {
402  bool exempt = false;
403  if ( fields.fieldOrigin( attributeIndex ) == QgsFields::OriginProvider
405  {
406  int providerIdx = fields.fieldOriginIndex( attributeIndex );
407  exempt = layer->dataProvider()->skipConstraintCheck( providerIdx, QgsFieldConstraints::ConstraintNotNull, value );
408  }
409 
410  if ( !exempt )
411  {
412  valid = valid && !value.isNull();
413 
414  if ( value.isNull() )
415  {
416  errors << QObject::tr( "value is NULL" );
417  }
418  }
419  }
420 
424  {
425  bool exempt = false;
426  if ( fields.fieldOrigin( attributeIndex ) == QgsFields::OriginProvider
428  {
429  int providerIdx = fields.fieldOriginIndex( attributeIndex );
430  exempt = layer->dataProvider()->skipConstraintCheck( providerIdx, QgsFieldConstraints::ConstraintUnique, value );
431  }
432 
433  if ( !exempt )
434  {
435  bool alreadyExists = QgsVectorLayerUtils::valueExists( layer, attributeIndex, value, QgsFeatureIds() << feature.id() );
436  valid = valid && !alreadyExists;
437 
438  if ( alreadyExists )
439  {
440  errors << QObject::tr( "value is not unique" );
441  }
442  }
443  }
444 
445  return valid;
446 }
447 
449  const QgsAttributeMap &attributes, QgsExpressionContext *context )
450 {
451  QgsFeatureList features { createFeatures( layer, QgsFeaturesDataList() << QgsFeatureData( geometry, attributes ), context ) };
452  return features.isEmpty() ? QgsFeature() : features.first();
453 }
454 
456 {
457  if ( !layer )
458  return QgsFeatureList();
459 
460  QgsFeatureList result;
461  result.reserve( featuresData.length() );
462 
463  QgsExpressionContext *evalContext = context;
464  std::unique_ptr< QgsExpressionContext > tempContext;
465  if ( !evalContext )
466  {
467  // no context passed, so we create a default one
469  evalContext = tempContext.get();
470  }
471 
472  QgsFields fields = layer->fields();
473 
474  // Cache unique values
475  QMap<int, QSet<QVariant>> uniqueValueCaches;
476 
477  for ( const auto &fd : qgis::as_const( featuresData ) )
478  {
479 
480  QgsFeature newFeature( fields );
481  newFeature.setValid( true );
482  newFeature.setGeometry( fd.geometry() );
483 
484  // initialize attributes
485  newFeature.initAttributes( fields.count() );
486  for ( int idx = 0; idx < fields.count(); ++idx )
487  {
488  QVariant v;
489  bool checkUnique = true;
490  const bool hasUniqueConstraint { static_cast<bool>( fields.at( idx ).constraints().constraints() & QgsFieldConstraints::ConstraintUnique ) };
491 
492  // in order of priority:
493  // 1. passed attribute value and if field does not have a unique constraint like primary key
494  if ( fd.attributes().contains( idx ) )
495  {
496  v = fd.attributes().value( idx );
497  }
498 
499  // Cache unique values
500  if ( hasUniqueConstraint && ! uniqueValueCaches.contains( idx ) )
501  {
502  // If the layer is filtered, get unique values from an unfiltered clone
503  if ( ! layer->subsetString().isEmpty() )
504  {
505  std::unique_ptr<QgsVectorLayer> unfilteredClone { layer->clone( ) };
506  unfilteredClone->setSubsetString( QString( ) );
507  uniqueValueCaches[ idx ] = unfilteredClone->uniqueValues( idx );
508  }
509  else
510  {
511  uniqueValueCaches[ idx ] = layer->uniqueValues( idx );
512  }
513  }
514 
515  // 2. client side default expression
516  // note - deliberately not using else if!
517  QgsDefaultValue defaultValueDefinition = layer->defaultValueDefinition( idx );
518  if ( ( v.isNull() || ( hasUniqueConstraint
519  && uniqueValueCaches[ idx ].contains( v ) )
520  || defaultValueDefinition.applyOnUpdate() )
521  && defaultValueDefinition.isValid() )
522  {
523  // client side default expression set - takes precedence over all. Why? Well, this is the only default
524  // which QGIS users have control over, so we assume that they're deliberately overriding any
525  // provider defaults for some good reason and we should respect that
526  v = layer->defaultValue( idx, newFeature, evalContext );
527  }
528 
529  // 3. provider side default value clause
530  // note - not an else if deliberately. Users may return null from a default value expression to fallback to provider defaults
531  if ( ( v.isNull() || ( hasUniqueConstraint
532  && uniqueValueCaches[ idx ].contains( v ) ) )
533  && fields.fieldOrigin( idx ) == QgsFields::OriginProvider )
534  {
535  int providerIndex = fields.fieldOriginIndex( idx );
536  QString providerDefault = layer->dataProvider()->defaultValueClause( providerIndex );
537  if ( !providerDefault.isEmpty() )
538  {
539  v = providerDefault;
540  checkUnique = false;
541  }
542  }
543 
544  // 4. provider side default literal
545  // note - deliberately not using else if!
546  if ( ( v.isNull() || ( checkUnique && hasUniqueConstraint
547  && uniqueValueCaches[ idx ].contains( v ) ) )
548  && fields.fieldOrigin( idx ) == QgsFields::OriginProvider )
549  {
550  int providerIndex = fields.fieldOriginIndex( idx );
551  v = layer->dataProvider()->defaultValue( providerIndex );
552  if ( v.isValid() )
553  {
554  //trust that the provider default has been sensibly set not to violate any constraints
555  checkUnique = false;
556  }
557  }
558 
559  // 5. passed attribute value
560  // note - deliberately not using else if!
561  if ( v.isNull() && fd.attributes().contains( idx ) )
562  {
563  v = fd.attributes().value( idx );
564  }
565 
566  // last of all... check that unique constraints are respected
567  // we can't handle not null or expression constraints here, since there's no way to pick a sensible
568  // value if the constraint is violated
569  if ( checkUnique && hasUniqueConstraint )
570  {
571  if ( uniqueValueCaches[ idx ].contains( v ) )
572  {
573  // unique constraint violated
574  QVariant uniqueValue = QgsVectorLayerUtils::createUniqueValueFromCache( layer, idx, uniqueValueCaches[ idx ], v );
575  if ( uniqueValue.isValid() )
576  v = uniqueValue;
577  }
578  }
579  if ( hasUniqueConstraint )
580  uniqueValueCaches[ idx ].insert( v );
581  newFeature.setAttribute( idx, v );
582  }
583  result.append( newFeature );
584  }
585  return result;
586 }
587 
588 QgsFeature QgsVectorLayerUtils::duplicateFeature( QgsVectorLayer *layer, const QgsFeature &feature, QgsProject *project, int depth, QgsDuplicateFeatureContext &duplicateFeatureContext )
589 {
590  if ( !layer )
591  return QgsFeature();
592 
593  if ( !layer->isEditable() )
594  return QgsFeature();
595 
596  //get context from layer
598  context.setFeature( feature );
599 
600  QgsFeature newFeature = createFeature( layer, feature.geometry(), feature.attributes().toMap(), &context );
601 
602  const QList<QgsRelation> relations = project->relationManager()->referencedRelations( layer );
603 
604  for ( const QgsRelation &relation : relations )
605  {
606  //check if composition (and not association)
607  if ( relation.strength() == QgsRelation::Composition && depth < 1 )
608  {
609  depth++;
610  //get features connected over this relation
611  QgsFeatureIterator relatedFeaturesIt = relation.getRelatedFeatures( feature );
612  QgsFeatureIds childFeatureIds;
613  QgsFeature childFeature;
614  while ( relatedFeaturesIt.nextFeature( childFeature ) )
615  {
616  //set childlayer editable
617  relation.referencingLayer()->startEditing();
618  //change the fk of the child to the id of the new parent
619  const auto pairs = relation.fieldPairs();
620  for ( const QgsRelation::FieldPair &fieldPair : pairs )
621  {
622  childFeature.setAttribute( fieldPair.first, newFeature.attribute( fieldPair.second ) );
623  }
624  //call the function for the child
625  childFeatureIds.insert( duplicateFeature( relation.referencingLayer(), childFeature, project, depth, duplicateFeatureContext ).id() );
626  }
627 
628  //store for feedback
629  duplicateFeatureContext.setDuplicatedFeatures( relation.referencingLayer(), childFeatureIds );
630  }
631  }
632 
633  layer->addFeature( newFeature );
634 
635  return newFeature;
636 }
637 
638 std::unique_ptr<QgsVectorLayerFeatureSource> QgsVectorLayerUtils::getFeatureSource( QPointer<QgsVectorLayer> layer, QgsFeedback *feedback )
639 {
640  std::unique_ptr<QgsVectorLayerFeatureSource> featureSource;
641 
642  auto getFeatureSource = [ layer, &featureSource, feedback ]
643  {
644 #if QT_VERSION >= QT_VERSION_CHECK( 5, 10, 0 )
645  Q_ASSERT( QThread::currentThread() == qApp->thread() || feedback );
646 #else
647  Q_UNUSED( feedback )
648 #endif
649  QgsVectorLayer *lyr = layer.data();
650 
651  if ( lyr )
652  {
653  featureSource.reset( new QgsVectorLayerFeatureSource( lyr ) );
654  }
655  };
656 
658 
659  return featureSource;
660 }
661 
663 {
664  if ( !feature.fields().isEmpty() )
665  {
666  QgsAttributes attributes;
667  attributes.reserve( fields.size() );
668  // feature has a field mapping, so we can match attributes to field names
669  for ( const QgsField &field : fields )
670  {
671  int index = feature.fields().lookupField( field.name() );
672  attributes.append( index >= 0 ? feature.attribute( index ) : QVariant( field.type() ) );
673  }
674  feature.setAttributes( attributes );
675  }
676  else
677  {
678  // no field name mapping in feature, just use order
679  const int lengthDiff = feature.attributes().count() - fields.count();
680  if ( lengthDiff > 0 )
681  {
682  // truncate extra attributes
683  QgsAttributes attributes = feature.attributes().mid( 0, fields.count() );
684  feature.setAttributes( attributes );
685  }
686  else if ( lengthDiff < 0 )
687  {
688  // add missing null attributes
689  QgsAttributes attributes = feature.attributes();
690  attributes.reserve( fields.count() );
691  for ( int i = feature.attributes().count(); i < fields.count(); ++i )
692  {
693  attributes.append( QVariant( fields.at( i ).type() ) );
694  }
695  feature.setAttributes( attributes );
696  }
697  }
698  feature.setFields( fields );
699 }
700 
702 {
703  QgsWkbTypes::Type inputWkbType( layer->wkbType( ) );
704  QgsFeatureList resultFeatures;
705  QgsFeature newF( feature );
706  // Fix attributes
708  // Does geometry need transformations?
710  bool newFHasGeom = newFGeomType !=
711  QgsWkbTypes::GeometryType::UnknownGeometry &&
712  newFGeomType != QgsWkbTypes::GeometryType::NullGeometry;
713  bool layerHasGeom = inputWkbType !=
714  QgsWkbTypes::Type::NoGeometry &&
715  inputWkbType != QgsWkbTypes::Type::Unknown;
716  // Drop geometry if layer is geometry-less
717  if ( newFHasGeom && ! layerHasGeom )
718  {
719  QgsFeature _f = QgsFeature( layer->fields() );
720  _f.setAttributes( newF.attributes() );
721  resultFeatures.append( _f );
722  }
723  else
724  {
725  // Geometry need fixing
726  if ( newFHasGeom && layerHasGeom && newF.geometry().wkbType() != inputWkbType )
727  {
728  // Curved -> straight
729  if ( !QgsWkbTypes::isCurvedType( inputWkbType ) && QgsWkbTypes::isCurvedType( newF.geometry().wkbType() ) )
730  {
731  QgsGeometry newGeom( newF.geometry().constGet()->segmentize() );
732  newF.setGeometry( newGeom );
733  }
734 
735  // polygon -> line
736  if ( QgsWkbTypes::geometryType( inputWkbType ) == QgsWkbTypes::LineGeometry &&
738  {
739  // boundary gives us a (multi)line string of exterior + interior rings
740  QgsGeometry newGeom( newF.geometry().constGet()->boundary() );
741  newF.setGeometry( newGeom );
742  }
743  // line -> polygon
746  {
747  std::unique_ptr< QgsGeometryCollection > gc( QgsGeometryFactory::createCollectionOfType( inputWkbType ) );
748  const QgsGeometry source = newF.geometry();
749  for ( auto part = source.const_parts_begin(); part != source.const_parts_end(); ++part )
750  {
751  std::unique_ptr< QgsAbstractGeometry > exterior( ( *part )->clone() );
752  if ( QgsCurve *curve = qgsgeometry_cast< QgsCurve * >( exterior.get() ) )
753  {
754  if ( QgsWkbTypes::isCurvedType( inputWkbType ) )
755  {
756  std::unique_ptr< QgsCurvePolygon > cp = qgis::make_unique< QgsCurvePolygon >();
757  cp->setExteriorRing( curve );
758  exterior.release();
759  gc->addGeometry( cp.release() );
760  }
761  else
762  {
763  std::unique_ptr< QgsPolygon > p = qgis::make_unique< QgsPolygon >();
764  p->setExteriorRing( qgsgeometry_cast< QgsLineString * >( curve ) );
765  exterior.release();
766  gc->addGeometry( p.release() );
767  }
768  }
769  }
770  QgsGeometry newGeom( std::move( gc ) );
771  newF.setGeometry( newGeom );
772  }
773 
774  // line/polygon -> points
775  if ( QgsWkbTypes::geometryType( inputWkbType ) == QgsWkbTypes::PointGeometry &&
776  ( newF.geometry().type() == QgsWkbTypes::LineGeometry ||
778  {
779  // lines/polygons to a point layer, extract all vertices
780  std::unique_ptr< QgsMultiPoint > mp = qgis::make_unique< QgsMultiPoint >();
781  const QgsGeometry source = newF.geometry();
782  QSet< QgsPoint > added;
783  for ( auto vertex = source.vertices_begin(); vertex != source.vertices_end(); ++vertex )
784  {
785  if ( added.contains( *vertex ) )
786  continue; // avoid duplicate points, e.g. start/end of rings
787  mp->addGeometry( ( *vertex ).clone() );
788  added.insert( *vertex );
789  }
790  QgsGeometry newGeom( std::move( mp ) );
791  newF.setGeometry( newGeom );
792  }
793 
794  // Single -> multi
795  if ( QgsWkbTypes::isMultiType( inputWkbType ) && ! newF.geometry().isMultipart( ) )
796  {
797  QgsGeometry newGeom( newF.geometry( ) );
798  newGeom.convertToMultiType();
799  newF.setGeometry( newGeom );
800  }
801  // Drop Z/M
802  if ( newF.geometry().constGet()->is3D() && ! QgsWkbTypes::hasZ( inputWkbType ) )
803  {
804  QgsGeometry newGeom( newF.geometry( ) );
805  newGeom.get()->dropZValue();
806  newF.setGeometry( newGeom );
807  }
808  if ( newF.geometry().constGet()->isMeasure() && ! QgsWkbTypes::hasM( inputWkbType ) )
809  {
810  QgsGeometry newGeom( newF.geometry( ) );
811  newGeom.get()->dropMValue();
812  newF.setGeometry( newGeom );
813  }
814  // Add Z/M back, set to 0
815  if ( ! newF.geometry().constGet()->is3D() && QgsWkbTypes::hasZ( inputWkbType ) )
816  {
817  QgsGeometry newGeom( newF.geometry( ) );
818  newGeom.get()->addZValue( 0.0 );
819  newF.setGeometry( newGeom );
820  }
821  if ( ! newF.geometry().constGet()->isMeasure() && QgsWkbTypes::hasM( inputWkbType ) )
822  {
823  QgsGeometry newGeom( newF.geometry( ) );
824  newGeom.get()->addMValue( 0.0 );
825  newF.setGeometry( newGeom );
826  }
827  // Multi -> single
828  if ( ! QgsWkbTypes::isMultiType( inputWkbType ) && newF.geometry().isMultipart( ) )
829  {
830  QgsGeometry newGeom( newF.geometry( ) );
831  const QgsGeometryCollection *parts( static_cast< const QgsGeometryCollection * >( newGeom.constGet() ) );
832  QgsAttributeMap attrMap;
833  for ( int j = 0; j < newF.fields().count(); j++ )
834  {
835  attrMap[j] = newF.attribute( j );
836  }
837  resultFeatures.reserve( parts->partCount() );
838  for ( int i = 0; i < parts->partCount( ); i++ )
839  {
840  QgsGeometry g( parts->geometryN( i )->clone() );
841  QgsFeature _f( createFeature( layer, g, attrMap ) );
842  resultFeatures.append( _f );
843  }
844  }
845  else
846  {
847  resultFeatures.append( newF );
848  }
849  }
850  else
851  {
852  resultFeatures.append( newF );
853  }
854  }
855  return resultFeatures;
856 }
857 
859 {
860  QgsFeatureList resultFeatures;
861  for ( const QgsFeature &f : features )
862  {
863  const QgsFeatureList features( makeFeatureCompatible( f, layer ) );
864  for ( const auto &_f : features )
865  {
866  resultFeatures.append( _f );
867  }
868  }
869  return resultFeatures;
870 }
871 
873 {
874  QList<QgsVectorLayer *> layers;
875  QMap<QgsVectorLayer *, QgsFeatureIds>::const_iterator i;
876  for ( i = mDuplicatedFeatures.begin(); i != mDuplicatedFeatures.end(); ++i )
877  layers.append( i.key() );
878  return layers;
879 }
880 
882 {
883  return mDuplicatedFeatures[layer];
884 }
885 
886 void QgsVectorLayerUtils::QgsDuplicateFeatureContext::setDuplicatedFeatures( QgsVectorLayer *layer, const QgsFeatureIds &ids )
887 {
888  mDuplicatedFeatures.insert( layer, ids );
889 }
890 /*
891 QMap<QgsVectorLayer *, QgsFeatureIds> QgsVectorLayerUtils::QgsDuplicateFeatureContext::duplicateFeatureContext() const
892 {
893  return mDuplicatedFeatures;
894 }
895 */
896 
898  mGeometry( geometry ),
899  mAttributes( attributes )
900 {}
901 
903 {
904  return mGeometry;
905 }
906 
908 {
909  return mAttributes;
910 }
911 
912 bool _fieldIsEditable( const QgsVectorLayer *layer, int fieldIndex, const QgsFeature &feature )
913 {
914  return layer->isEditable() &&
915  !layer->editFormConfig().readOnly( fieldIndex ) &&
916  ( ( layer->dataProvider() && layer->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeAttributeValues ) || FID_IS_NEW( feature.id() ) );
917 }
918 
919 bool QgsVectorLayerUtils::fieldIsEditable( const QgsVectorLayer *layer, int fieldIndex, const QgsFeature &feature )
920 {
921  if ( layer->fields().fieldOrigin( fieldIndex ) == QgsFields::OriginJoin )
922  {
923  int srcFieldIndex;
924  const QgsVectorLayerJoinInfo *info = layer->joinBuffer()->joinForFieldIndex( fieldIndex, layer->fields(), srcFieldIndex );
925 
926  if ( !info || !info->isEditable() )
927  return false;
928 
929  // check that joined feature exist, else it is not editable
930  if ( !info->hasUpsertOnEdit() )
931  {
932  const QgsFeature joinedFeature = layer->joinBuffer()->joinedFeatureOf( info, feature );
933  if ( !joinedFeature.isValid() )
934  return false;
935  }
936 
937  return _fieldIsEditable( info->joinLayer(), srcFieldIndex, feature );
938  }
939  else
940  return _fieldIsEditable( layer, fieldIndex, feature );
941 }
942 
943 QHash<QString, QHash<QString, QSet<QgsSymbolLayerId>>> QgsVectorLayerUtils::labelMasks( const QgsVectorLayer *layer )
944 {
945  class LabelMasksVisitor : public QgsStyleEntityVisitorInterface
946  {
947  public:
948  bool visitEnter( const QgsStyleEntityVisitorInterface::Node &node ) override
949  {
951  {
952  currentRule = node.identifier;
953  return true;
954  }
955  return false;
956  }
957  bool visit( const QgsStyleEntityVisitorInterface::StyleLeaf &leaf ) override
958  {
959  if ( leaf.entity && leaf.entity->type() == QgsStyle::LabelSettingsEntity )
960  {
961  auto labelSettingsEntity = static_cast<const QgsStyleLabelSettingsEntity *>( leaf.entity );
962  if ( labelSettingsEntity->settings().format().mask().enabled() )
963  {
964  for ( const auto &r : labelSettingsEntity->settings().format().mask().maskedSymbolLayers() )
965  {
966  masks[currentRule][r.layerId()].insert( r.symbolLayerId() );
967  }
968  }
969  }
970  return true;
971  }
972 
973  QHash<QString, QHash<QString, QSet<QgsSymbolLayerId>>> masks;
974  // Current label rule, empty string for a simple labeling
975  QString currentRule;
976  };
977 
978  if ( ! layer->labeling() )
979  return {};
980 
981  LabelMasksVisitor visitor;
982  layer->labeling()->accept( &visitor );
983  return std::move( visitor.masks );
984 }
985 
986 QHash<QString, QSet<QgsSymbolLayerId>> QgsVectorLayerUtils::symbolLayerMasks( const QgsVectorLayer *layer )
987 {
988  if ( ! layer->renderer() )
989  return {};
990 
991  class SymbolLayerVisitor : public QgsStyleEntityVisitorInterface
992  {
993  public:
994  bool visitEnter( const QgsStyleEntityVisitorInterface::Node &node ) override
995  {
997  }
998 
999  void visitSymbol( const QgsSymbol *symbol )
1000  {
1001  for ( int idx = 0; idx < symbol->symbolLayerCount(); idx++ )
1002  {
1003  const QgsSymbolLayer *sl = symbol->symbolLayer( idx );
1004  for ( const auto &mask : sl->masks() )
1005  {
1006  masks[mask.layerId()].insert( mask.symbolLayerId() );
1007  }
1008  // recurse over sub symbols
1009  const QgsSymbol *subSymbol = const_cast<QgsSymbolLayer *>( sl )->subSymbol();
1010  if ( subSymbol )
1011  visitSymbol( subSymbol );
1012  }
1013  }
1014 
1015  bool visit( const QgsStyleEntityVisitorInterface::StyleLeaf &leaf ) override
1016  {
1017  if ( leaf.entity && leaf.entity->type() == QgsStyle::SymbolEntity )
1018  {
1019  auto symbolEntity = static_cast<const QgsStyleSymbolEntity *>( leaf.entity );
1020  if ( symbolEntity->symbol() )
1021  visitSymbol( symbolEntity->symbol() );
1022  }
1023  return true;
1024  }
1025  QHash<QString, QSet<QgsSymbolLayerId>> masks;
1026  };
1027 
1028  SymbolLayerVisitor visitor;
1029  layer->renderer()->accept( &visitor );
1030  return visitor.masks;
1031 }
1032 
1034 {
1036 
1037  QgsExpression exp( layer->displayExpression() );
1038  context.setFeature( feature );
1039  exp.prepare( &context );
1040  QString displayString = exp.evaluate( &context ).toString();
1041 
1042  return displayString;
1043 }
bool isMeasure() const
Returns true if the geometry contains m values.
int lookupField(const QString &fieldName) const
Looks up field&#39;s index from the field name.
Definition: qgsfields.cpp:324
bool _fieldIsEditable(const QgsVectorLayer *layer, int fieldIndex, const QgsFeature &feature)
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:183
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:971
Field comes from a joined layer (originIndex / 1000 = index of the join, originIndex % 1000 = index w...
Definition: qgsfields.h:50
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeatureid.h:34
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:162
bool isMultipart() const
Returns true if WKB of the geometry is of WKBMulti* type.
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:62
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.
static bool isMultiType(Type type)
Returns true if the WKB type is a multi type.
Definition: qgswkbtypes.h:706
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:571
QgsWkbTypes::Type wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
ConstraintOrigin
Origin of constraints.
static QList< double > getDoubleValues(const QgsVectorLayer *layer, const QString &fieldOrExpression, bool &ok, bool selectedOnly=false, int *nullCount=nullptr, QgsFeedback *feedback=nullptr)
Fetches all double values from a specified field name or expression.
QgsAbstractGeometry::const_part_iterator const_parts_end() const
Returns STL-style iterator pointing to the imaginary part after the last part of the geometry...
QgsAbstractGeometry::const_part_iterator const_parts_begin() const
Returns STL-style const iterator pointing to the first part of the geometry.
static QgsFeatureList createFeatures(const QgsVectorLayer *layer, const QgsFeaturesDataList &featuresData, QgsExpressionContext *context=nullptr)
Creates a set of new features ready for insertion into a layer.
QVariant evaluate()
Evaluate the feature and return the result.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
bool convertCompatible(QVariant &v) const
Converts the provided variant to a compatible format.
Definition: qgsfield.cpp:316
static std::unique_ptr< QgsGeometryCollection > createCollectionOfType(QgsWkbTypes::Type type)
Returns a new geometry collection matching a specified WKB type.
Container of fields for a vector layer.
Definition: qgsfields.h:42
virtual bool addMValue(double mValue=0)=0
Adds a measure to the geometry, initialized to a preset value.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:122
void setAttributes(const QgsAttributes &attrs)
Sets the feature&#39;s attributes.
Definition: qgsfeature.cpp:127
bool setAttribute(int field, const QVariant &attr)
Set an attribute&#39;s value by field index.
Definition: qgsfeature.cpp:211
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:182
virtual QgsAbstractGeometry * boundary() const =0
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
Stores information about constraints which may be present on a field.
Field comes from the underlying data provider of the vector layer (originIndex = index in provider&#39;s ...
Definition: qgsfields.h:49
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h: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 bool hasZ(Type type)
Tests whether a WKB type contains the z-dimension.
Definition: qgswkbtypes.h:917
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().
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:45
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:68
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...
Geometry collection.
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:202
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
static GeometryType geometryType(Type type)
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
Definition: qgswkbtypes.h:812
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:91
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.
Abstract base class for curved geometry type.
Definition: qgscurve.h:35
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:102
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:362
QString displayExpression
static QgsFeatureList makeFeaturesCompatible(const QgsFeatureList &features, const QgsVectorLayer *layer)
Converts input features to be compatible with the given layer.
QgsVectorLayerJoinBuffer * joinBuffer()
Returns the join buffer object.
Partial snapshot of vector layer&#39;s state (only the members necessary for access to features) ...
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
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:139
#define FID_IS_NEW(fid)
Definition: qgsfeatureid.h:28
void setValid(bool validity)
Sets the validity of the feature.
Definition: qgsfeature.cpp:188
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 convertToMultiType()
Converts single type geometry into multitype geometry e.g.
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:55
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.
static QgsFeature duplicateFeature(QgsVectorLayer *layer, const QgsFeature &feature, QgsProject *project, int depth, QgsDuplicateFeatureContext &duplicateFeatureContext)
Duplicates a feature and it&#39;s children (one level deep).
static bool isCurvedType(Type type)
Returns true if the WKB type is a curved type or can contain curved geometries.
Definition: qgswkbtypes.h:755
virtual bool addZValue(double zValue=0)=0
Adds a z-dimension to the geometry, initialized to a preset value.
QgsFeatureIds duplicatedFeatures(QgsVectorLayer *layer) const
Returns the duplicated features in the given layer.
A label settings entity for QgsStyle databases.
Definition: qgsstyle.h:1064
void setGeometry(const QgsGeometry &geometry)
Set the feature&#39;s geometry.
Definition: qgsfeature.cpp:137
const QgsVectorLayerJoinInfo * joinForFieldIndex(int index, const QgsFields &fields, int &sourceFieldIndex) const
Finds the vector join for a layer field index.
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=nullptr) FINAL
Adds a single feature to the sink.
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.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
bool isNumeric
Definition: qgsfield.h:53
static bool hasM(Type type)
Tests whether a WKB type contains m values.
Definition: qgswkbtypes.h:967
ConstraintOrigin constraintOrigin(Constraint constraint) const
Returns the origin of a field constraint, or ConstraintOriginNotSet if the constraint is not present ...
void appendScopes(const QList< QgsExpressionContextScope *> &scopes)
Appends a list of scopes to the end of the context.
QgsWkbTypes::GeometryType type
Definition: qgsgeometry.h:126
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. ...
virtual bool dropMValue()=0
Drops any measure values which exist in the geometry.
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...
QString constraintExpression() const
Returns the constraint expression for the field, if set.
static QgsFeatureList makeFeatureCompatible(const QgsFeature &feature, const QgsVectorLayer *layer)
Converts input feature to be compatible with the given layer.
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:262
virtual QgsAbstractGeometry * segmentize(double tolerance=M_PI/180., SegmentationToleranceType toleranceType=MaximumAngle) const
Returns a version of the geometry without curves.
static bool fieldIsEditable(const QgsVectorLayer *layer, int fieldIndex, const QgsFeature &feature)
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
Allows modification of attribute values.
Contains information relating to the style entity currently being visited.
QVariant::Type type
Definition: qgsfield.h:57
virtual bool dropZValue()=0
Drops any z-dimensions which exist in the geometry.
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...