QGIS API Documentation  3.14.0-Pi (9f7028fd23)
qgsvectorlayerfeatureiterator.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsvectorlayerfeatureiterator.cpp
3  ---------------------
4  begin : Dezember 2012
5  copyright : (C) 2012 by Martin Dobias
6  email : wonder dot sk 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  ***************************************************************************/
16 
18 #include "qgsgeometrysimplifier.h"
19 #include "qgssimplifymethod.h"
20 #include "qgsvectordataprovider.h"
22 #include "qgsvectorlayer.h"
24 #include "qgsexpressioncontext.h"
25 #include "qgsdistancearea.h"
26 #include "qgsproject.h"
27 #include "qgsmessagelog.h"
28 #include "qgsexception.h"
30 
32 {
33  QMutexLocker locker( &layer->mFeatureSourceConstructorMutex );
35  mFields = layer->fields();
36  mId = layer->id();
37 
38  // update layer's join caches if necessary
39  if ( layer->mJoinBuffer->containsJoins() )
40  layer->mJoinBuffer->createJoinCaches();
41 
42  mJoinBuffer = layer->mJoinBuffer->clone();
43 
44  mExpressionFieldBuffer = new QgsExpressionFieldBuffer( *layer->mExpressionFieldBuffer );
45  mCrs = layer->crs();
46 
47  mHasEditBuffer = layer->editBuffer();
48  if ( mHasEditBuffer )
49  {
50 #if 0
51  // TODO[MD]: after merge
52  if ( request.filterType() == QgsFeatureRequest::FilterFid )
53  {
54 
55  // only copy relevant parts
56  if ( L->editBuffer()->addedFeatures().contains( request.filterFid() ) )
57  mAddedFeatures.insert( request.filterFid(), L->editBuffer()->addedFeatures()[ request.filterFid()] );
58 
59  if ( L->editBuffer()->changedGeometries().contains( request.filterFid() ) )
60  mChangedGeometries.insert( request.filterFid(), L->editBuffer()->changedGeometries()[ request.filterFid()] );
61 
62  if ( L->editBuffer()->deletedFeatureIds().contains( request.filterFid() ) )
63  mDeletedFeatureIds.insert( request.filterFid() );
64 
65  if ( L->editBuffer()->changedAttributeValues().contains( request.filterFid() ) )
66  mChangedAttributeValues.insert( request.filterFid(), L->editBuffer()->changedAttributeValues()[ request.filterFid()] );
67 
68  if ( L->editBuffer()->changedAttributeValues().contains( request.filterFid() ) )
69  mChangedFeaturesRequest.setFilterFids( QgsFeatureIds() << request.filterFid() );
70  }
71  else
72  {
73 #endif
78  mAddedAttributes = QList<QgsField>( layer->editBuffer()->addedAttributes() );
80 #if 0
81  }
82 #endif
83  }
84 
85  std::unique_ptr< QgsExpressionContextScope > layerScope( QgsExpressionContextUtils::layerScope( layer ) );
86  mLayerScope = *layerScope;
87 }
88 
90 {
91  delete mJoinBuffer;
94 }
95 
97 {
98  // return feature iterator that does not own this source
99  return QgsFeatureIterator( new QgsVectorLayerFeatureIterator( this, false, request ) );
100 }
101 
103 {
104  return mFields;
105 }
106 
108 {
109  return mCrs;
110 }
111 
113 {
114  return mId;
115 }
116 
117 
120  , mFetchedFid( false )
121 
122 {
124  {
126  }
127  try
128  {
130  }
131  catch ( QgsCsException & )
132  {
133  // can't reproject mFilterRect
134  close();
135  return;
136  }
137  if ( !mFilterRect.isNull() )
138  {
139  // update request to be the unprojected filter rect
141  }
142 
144  {
147 
149  {
150  //ensure that all fields required for filter expressions are prepared
152  attributeIndexes += qgis::listToSet( mRequest.subsetOfAttributes() );
153  mRequest.setSubsetOfAttributes( qgis::setToList( attributeIndexes ) );
154  }
155  }
156 
157  prepareFields();
158 
159  mHasVirtualAttributes = !mFetchJoinInfo.isEmpty() || !mExpressionFieldInfo.isEmpty();
160 
161  // by default provider's request is the same
163  // but we remove any destination CRS parameter - that is handled in QgsVectorLayerFeatureIterator,
164  // not at the provider level. Otherwise virtual fields depending on geometry would have incorrect
165  // values
166  if ( mRequest.destinationCrs().isValid() )
167  {
169  }
170 
172  {
173  // prepare list of attributes to match provider fields
174  QSet<int> providerSubset;
176  int nPendingFields = mSource->mFields.count();
177  for ( int attrIndex : subset )
178  {
179  if ( attrIndex < 0 || attrIndex >= nPendingFields )
180  continue;
181  if ( mSource->mFields.fieldOrigin( attrIndex ) == QgsFields::OriginProvider )
182  providerSubset << mSource->mFields.fieldOriginIndex( attrIndex );
183  }
184 
185  // This is done in order to be prepared to do fallback order bys
186  // and be sure we have the required columns.
187  // TODO:
188  // It would be nicer to first check if we can compile the order by
189  // and only modify the subset if we cannot.
190  if ( !mProviderRequest.orderBy().isEmpty() )
191  {
192  const auto usedAttributeIndices = mProviderRequest.orderBy().usedAttributeIndices( mSource->mFields );
193  for ( int attrIndex : usedAttributeIndices )
194  {
195  providerSubset << attrIndex;
196  }
197  }
198 
199  mProviderRequest.setSubsetOfAttributes( qgis::setToList( providerSubset ) );
200  }
201 
203  {
204  const bool needsGeom = mProviderRequest.filterExpression()->needsGeometry();
205  const auto constReferencedColumns = mProviderRequest.filterExpression()->referencedColumns();
206  for ( const QString &field : constReferencedColumns )
207  {
208  int idx = source->mFields.lookupField( field );
209 
210  // If there are fields in the expression which are not of origin provider, the provider will not be able to filter based on them.
211  // In this case we disable the expression filter.
212  if ( source->mFields.fieldOrigin( idx ) != QgsFields::OriginProvider )
213  {
215  // can't limit at provider side
217  if ( needsGeom )
218  {
219  // have to get geometry from provider in order to evaluate expression on client
221  }
222  break;
223  }
224  }
225  }
226 
227  if ( mSource->mHasEditBuffer )
228  {
230  QgsFeatureIds changedIds;
231  QgsChangedAttributesMap::const_iterator attIt = mSource->mChangedAttributeValues.constBegin();
232  for ( ; attIt != mSource->mChangedAttributeValues.constEnd(); ++attIt )
233  {
234  changedIds << attIt.key();
235  }
237 
238  if ( mChangedFeaturesRequest.limit() > 0 )
239  {
240  int providerLimit = mProviderRequest.limit();
241 
242  // features may be deleted in buffer, so increase limit sent to provider
243  providerLimit += mSource->mDeletedFeatureIds.size();
244 
246  {
247  // attribute changes may mean some features no longer match expression, so increase limit sent to provider
248  providerLimit += mSource->mChangedAttributeValues.size();
249  }
250 
252  {
253  // geometry changes may mean some features no longer match expression or rect, so increase limit sent to provider
254  providerLimit += mSource->mChangedGeometries.size();
255  }
256 
257  mProviderRequest.setLimit( providerLimit );
258  mChangedFeaturesRequest.setLimit( providerLimit );
259  }
260  }
261 
262  if ( request.filterType() == QgsFeatureRequest::FilterFid )
263  {
264  mFetchedFid = false;
265  }
266  else // no filter or filter by rect
267  {
268  if ( mSource->mHasEditBuffer )
269  {
271  }
272  else
273  {
275  }
276 
278  }
279 }
280 
281 
283 {
284  qDeleteAll( mExpressionFieldInfo );
285 
286  close();
287 }
288 
290 
296 class QgsThreadStackOverflowGuard
297 {
298  public:
299 
300  QgsThreadStackOverflowGuard( QThreadStorage<QStack<QString>> &storage, const QString &stackFrameInformation, int maxDepth )
301  : mStorage( storage )
302  , mMaxDepth( maxDepth )
303  {
304  if ( !storage.hasLocalData() )
305  {
306  storage.setLocalData( QStack<QString>() );
307  }
308 
309  storage.localData().push( stackFrameInformation );
310  }
311 
312  ~QgsThreadStackOverflowGuard()
313  {
314  mStorage.localData().pop();
315  }
316 
317  bool hasStackOverflow() const
318  {
319  if ( mStorage.localData().size() > mMaxDepth )
320  return true;
321  else
322  return false;
323  }
324 
325  QString topFrames() const
326  {
327  QStringList dumpStack;
328  const QStack<QString> &stack = mStorage.localData();
329 
330  int dumpSize = std::min( stack.size(), 10 );
331  for ( int i = 0; i < dumpSize; ++i )
332  {
333  dumpStack += stack.at( i );
334  }
335 
336  return dumpStack.join( '\n' );
337  }
338 
339  int depth() const
340  {
341  return mStorage.localData().size();
342  }
343 
344  private:
345  QThreadStorage<QStack<QString>> &mStorage;
346  int mMaxDepth;
347 };
348 
350 
352 {
353  f.setValid( false );
354 
355  if ( mClosed )
356  return false;
357 
358  static QThreadStorage<QStack<QString>> sStack;
359 
360  QgsThreadStackOverflowGuard guard( sStack, mSource->id(), 4 );
361 
362  if ( guard.hasStackOverflow() )
363  {
364  QgsMessageLog::logMessage( QObject::tr( "Stack overflow, too many nested feature iterators.\nIterated layers:\n%3\n..." ).arg( mSource->id(), guard.topFrames() ), QObject::tr( "General" ), Qgis::Critical );
365  return false;
366  }
367 
369  {
370  if ( mFetchedFid )
371  return false;
372  bool res = nextFeatureFid( f );
373  if ( res && postProcessFeature( f ) )
374  {
375  mFetchedFid = true;
376  return res;
377  }
378  else
379  {
380  return false;
381  }
382  }
383 
384  if ( !mFilterRect.isNull() )
385  {
386  if ( fetchNextChangedGeomFeature( f ) )
387  return true;
388 
389  // no more changed geometries
390  }
391 
393  {
395  return true;
396 
397  if ( fetchNextChangedGeomFeature( f ) )
398  return true;
399 
400  // no more changed features
401  }
402 
403  while ( fetchNextAddedFeature( f ) )
404  {
405  return true;
406  }
407  // no more added features
408 
409  if ( mProviderIterator.isClosed() )
410  {
413  mProviderIterator.setInterruptionChecker( mInterruptionChecker );
414  }
415 
416  while ( mProviderIterator.nextFeature( f ) )
417  {
418  if ( mFetchConsidered.contains( f.id() ) )
419  continue;
420 
421  // TODO[MD]: just one resize of attributes
422  f.setFields( mSource->mFields );
423 
424  // update attributes
425  if ( mSource->mHasEditBuffer )
427 
428  if ( mHasVirtualAttributes )
430 
432  {
433  //filtering by expression, and couldn't do it on the provider side
436  {
437  //feature did not match filter
438  continue;
439  }
440  }
441 
442  // update geometry
443  // TODO[MK]: FilterRect check after updating the geometry
446 
447  if ( !postProcessFeature( f ) )
448  continue;
449 
450  return true;
451  }
452  // no more provider features
453 
454  close();
455  return false;
456 }
457 
458 
459 
461 {
462  if ( mClosed )
463  return false;
464 
466  {
467  mFetchedFid = false;
468  }
469  else
470  {
473  }
474 
475  return true;
476 }
477 
479 {
480  if ( mClosed )
481  return false;
482 
484 
485  iteratorClosed();
486 
487  mClosed = true;
488  return true;
489 }
490 
492 {
493  mProviderIterator.setInterruptionChecker( interruptionChecker );
494  mInterruptionChecker = interruptionChecker;
495 }
496 
498 {
499  return mProviderIterator.isValid();
500 }
501 
503 {
504  while ( mFetchAddedFeaturesIt-- != mSource->mAddedFeatures.constBegin() )
505  {
507 
508  if ( mFetchConsidered.contains( fid ) )
509  // must have changed geometry outside rectangle
510  continue;
511 
513 
514  // can't test for feature acceptance until after calling useAddedFeature
515  // since acceptFeature may rely on virtual fields
516  if ( !mRequest.acceptFeature( f ) )
517  // skip features which are not accepted by the filter
518  continue;
519 
520  if ( !postProcessFeature( f ) )
521  continue;
522 
523  return true;
524  }
525 
527  return false; // no more added features
528 }
529 
530 
532 {
533  // since QgsFeature is implicitly shared, it's more efficient to just copy the
534  // whole feature, even if flags like NoGeometry or a subset of attributes is set at the request.
535  // This helps potentially avoid an unnecessary detach of the feature
536  f = src;
537  f.setValid( true );
538  f.setFields( mSource->mFields );
539 
540  if ( mHasVirtualAttributes )
542 }
543 
544 
545 
547 {
548  // check if changed geometries are in rectangle
550  {
551  QgsFeatureId fid = mFetchChangedGeomIt.key();
552 
553  if ( mFetchConsidered.contains( fid ) )
554  // skip deleted features
555  continue;
556 
557  mFetchConsidered << fid;
558 
559  if ( !mFilterRect.isNull() && !mFetchChangedGeomIt->intersects( mFilterRect ) )
560  // skip changed geometries not in rectangle and don't check again
561  continue;
562 
564 
566  {
569  {
570  continue;
571  }
572  }
573 
574  if ( postProcessFeature( f ) )
575  {
576  // return complete feature
578  return true;
579  }
580  }
581 
582  return false; // no more changed geometries
583 }
584 
586 {
588  {
589  if ( mFetchConsidered.contains( f.id() ) )
590  // skip deleted features and those already handled by the geometry
591  continue;
592 
593  mFetchConsidered << f.id();
594 
596 
597  if ( mHasVirtualAttributes )
599 
601  if ( mRequest.filterExpression()->evaluate( mRequest.expressionContext() ).toBool() && postProcessFeature( f ) )
602  {
603  return true;
604  }
605  }
606 
607  return false;
608 }
609 
610 
612 {
613  f.setId( fid );
614  f.setValid( true );
615  f.setFields( mSource->mFields );
616 
619  {
620  f.setGeometry( geom );
621  }
622 
623  bool subsetAttrs = ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes );
624  if ( !subsetAttrs || !mRequest.subsetOfAttributes().isEmpty() )
625  {
626  // retrieve attributes from provider
627  QgsFeature tmp;
628  //mDataProvider->featureAtId( fid, tmp, false, mFetchProvAttributes );
629  QgsFeatureRequest request;
631  if ( subsetAttrs )
632  {
634  }
636  if ( fi.nextFeature( tmp ) )
637  {
640  f.setAttributes( tmp.attributes() );
641  }
642  }
643 
645 }
646 
647 
648 
650 {
652 
655 }
656 
658 {
659  if ( !mSource->mFields.exists( fieldIdx ) )
660  return;
661 
662  if ( mSource->mFields.fieldOrigin( fieldIdx ) != QgsFields::OriginJoin )
663  return;
664 
665  int sourceLayerIndex;
666  const QgsVectorLayerJoinInfo *joinInfo = mSource->mJoinBuffer->joinForFieldIndex( fieldIdx, mSource->mFields, sourceLayerIndex );
667  Q_ASSERT( joinInfo );
668 
669  QgsVectorLayer *joinLayer = joinInfo->joinLayer();
670  if ( !joinLayer )
671  return; // invalid join (unresolved reference to layer)
672 
673  if ( !mFetchJoinInfo.contains( joinInfo ) )
674  {
675  FetchJoinInfo info;
676  info.joinInfo = joinInfo;
677  info.joinLayer = joinLayer;
680  info.joinField = joinLayer->fields().indexFromName( joinInfo->joinFieldName() );
681 
682  // for joined fields, we always need to request the targetField from the provider too
683  if ( !mPreparedFields.contains( info.targetField ) && !mFieldsToPrepare.contains( info.targetField ) )
684  mFieldsToPrepare << info.targetField;
685 
688 
689  mFetchJoinInfo.insert( joinInfo, info );
690  }
691 
692  // store field source index - we'll need it when fetching from provider
693  mFetchJoinInfo[ joinInfo ].attributes.push_back( sourceLayerIndex );
694 }
695 
696 
698 {
699  static QThreadStorage<QStack<QString>> sStack;
700 
701  QgsThreadStackOverflowGuard guard( sStack, mSource->id(), 4 );
702 
703  if ( guard.hasStackOverflow() )
704  {
705  QgsMessageLog::logMessage( QObject::tr( "Stack overflow when preparing field %1 of layer %2.\nLast frames:\n%3\n..." ).arg( mSource->fields().at( fieldIdx ).name(), mSource->id(), guard.topFrames() ), QObject::tr( "General" ), Qgis::Critical );
706  return;
707  }
708 
709  const QList<QgsExpressionFieldBuffer::ExpressionField> &exps = mSource->mExpressionFieldBuffer->expressions();
710 
711  int oi = mSource->mFields.fieldOriginIndex( fieldIdx );
712  std::unique_ptr<QgsExpression> exp = qgis::make_unique<QgsExpression>( exps[oi].cachedExpression );
713 
714  QgsDistanceArea da;
716  da.setEllipsoid( QgsProject::instance()->ellipsoid() );
717  exp->setGeomCalculator( &da );
718  exp->setDistanceUnits( QgsProject::instance()->distanceUnits() );
719  exp->setAreaUnits( QgsProject::instance()->areaUnits() );
720 
721  if ( !mExpressionContext )
722  createExpressionContext();
723  exp->prepare( mExpressionContext.get() );
724  const QSet<int> referencedColumns = exp->referencedAttributeIndexes( mSource->fields() );
725 
726  QSet<int> requestedAttributes = qgis::listToSet( mRequest.subsetOfAttributes() );
727 
728  for ( int dependentFieldIdx : referencedColumns )
729  {
731  {
732  requestedAttributes += dependentFieldIdx;
733  }
734  // also need to fetch this dependent field
735  if ( !mPreparedFields.contains( dependentFieldIdx ) && !mFieldsToPrepare.contains( dependentFieldIdx ) )
736  mFieldsToPrepare << dependentFieldIdx;
737  }
738 
740  {
741  mRequest.setSubsetOfAttributes( qgis::setToList( requestedAttributes ) );
742  }
743 
744  if ( exp->needsGeometry() )
745  {
747  }
748 
749  mExpressionFieldInfo.insert( fieldIdx, exp.release() );
750 }
751 
753 {
754  mPreparedFields.clear();
755  mFieldsToPrepare.clear();
756  mFetchJoinInfo.clear();
757  mOrderedJoinInfoList.clear();
758 
759  mExpressionContext.reset();
760 
762 
763  while ( !mFieldsToPrepare.isEmpty() )
764  {
765  int fieldIdx = mFieldsToPrepare.takeFirst();
766  if ( mPreparedFields.contains( fieldIdx ) )
767  continue;
768 
769  mPreparedFields << fieldIdx;
770  prepareField( fieldIdx );
771  }
772 
773  //sort joins by dependency
774  if ( !mFetchJoinInfo.empty() )
775  {
776  createOrderedJoinList();
777  }
778 }
779 
780 void QgsVectorLayerFeatureIterator::createOrderedJoinList()
781 {
782  mOrderedJoinInfoList = mFetchJoinInfo.values();
783  if ( mOrderedJoinInfoList.size() < 2 )
784  {
785  return;
786  }
787 
788  QSet<int> resolvedFields; //todo: get provider / virtual fields without joins
789 
790  //add all provider fields without joins as resolved fields
791  QList< int >::const_iterator prepFieldIt = mPreparedFields.constBegin();
792  for ( ; prepFieldIt != mPreparedFields.constEnd(); ++prepFieldIt )
793  {
794  if ( mSource->mFields.fieldOrigin( *prepFieldIt ) != QgsFields::OriginJoin )
795  {
796  resolvedFields.insert( *prepFieldIt );
797  }
798  }
799 
800  //iterate through the joins. If target field is not yet covered, move the entry to the end of the list
801 
802  //some join combinations might not have a resolution at all
803  int maxIterations = ( mOrderedJoinInfoList.size() + 1 ) * mOrderedJoinInfoList.size() / 2.0;
804  int currentIteration = 0;
805 
806  for ( int i = 0; i < mOrderedJoinInfoList.size() - 1; ++i )
807  {
808  if ( !resolvedFields.contains( mOrderedJoinInfoList.at( i ).targetField ) )
809  {
810  mOrderedJoinInfoList.append( mOrderedJoinInfoList.at( i ) );
811  mOrderedJoinInfoList.removeAt( i );
812  --i;
813  }
814  else
815  {
816  int offset = mOrderedJoinInfoList.at( i ).indexOffset;
817  int joinField = mOrderedJoinInfoList.at( i ).joinField;
818 
819  QgsAttributeList attributes = mOrderedJoinInfoList.at( i ).attributes;
820  for ( int n = 0; n < attributes.size(); n++ )
821  {
822  if ( n != joinField )
823  {
824  resolvedFields.insert( joinField < n ? n + offset - 1 : n + offset );
825  }
826  }
827  }
828 
829  ++currentIteration;
830  if ( currentIteration >= maxIterations )
831  {
832  break;
833  }
834  }
835 }
836 
837 bool QgsVectorLayerFeatureIterator::postProcessFeature( QgsFeature &feature )
838 {
839  bool result = checkGeometryValidity( feature );
840  if ( result )
842  return result;
843 }
844 
845 bool QgsVectorLayerFeatureIterator::checkGeometryValidity( const QgsFeature &feature )
846 {
847  if ( !feature.hasGeometry() )
848  return true;
849 
850  switch ( mRequest.invalidGeometryCheck() )
851  {
853  return true;
854 
856  {
857  if ( !feature.geometry().isGeosValid() )
858  {
859  QgsMessageLog::logMessage( QObject::tr( "Geometry error: One or more input features have invalid geometry." ), QString(), Qgis::Critical );
861  {
862  mRequest.invalidGeometryCallback()( feature );
863  }
864  return false;
865  }
866  break;
867  }
868 
870  if ( !feature.geometry().isGeosValid() )
871  {
872  QgsMessageLog::logMessage( QObject::tr( "Geometry error: One or more input features have invalid geometry." ), QString(), Qgis::Critical );
873  close();
875  {
876  mRequest.invalidGeometryCallback()( feature );
877  }
878  return false;
879  }
880  break;
881  }
882 
883  return true;
884 }
885 
887 {
888  switch ( mSource->mFields.fieldOrigin( fieldIdx ) )
889  {
891  prepareExpression( fieldIdx );
892  break;
893 
896  {
897  prepareJoin( fieldIdx );
898  }
899  break;
900 
904  break;
905  }
906 }
907 
909 {
910  QList< FetchJoinInfo >::const_iterator joinIt = mOrderedJoinInfoList.constBegin();
911  for ( ; joinIt != mOrderedJoinInfoList.constEnd(); ++joinIt )
912  {
913  QVariant targetFieldValue = f.attribute( joinIt->targetField );
914  if ( !targetFieldValue.isValid() )
915  continue;
916 
917  const QHash< QString, QgsAttributes> &memoryCache = joinIt->joinInfo->cachedAttributes;
918  if ( memoryCache.isEmpty() )
919  joinIt->addJoinedAttributesDirect( f, targetFieldValue );
920  else
921  joinIt->addJoinedAttributesCached( f, targetFieldValue );
922  }
923 }
924 
926 {
927  // make sure we have space for newly added attributes
928  QgsAttributes attr = f.attributes();
929  attr.resize( mSource->mFields.count() ); // Provider attrs count + joined attrs count + expression attrs count
930  f.setAttributes( attr );
931 
932  // possible TODO - handle combinations of expression -> join -> expression -> join?
933  // but for now, write that off as too complex and an unlikely rare, unsupported use case
934 
935  QList< int > fetchedVirtualAttributes;
936  //first, check through joins for any virtual fields we need
937  QMap<const QgsVectorLayerJoinInfo *, FetchJoinInfo>::const_iterator joinIt = mFetchJoinInfo.constBegin();
938  for ( ; joinIt != mFetchJoinInfo.constEnd(); ++joinIt )
939  {
940  if ( mExpressionFieldInfo.contains( joinIt->targetField ) )
941  {
942  // have to calculate expression field before we can handle this join
943  addExpressionAttribute( f, joinIt->targetField );
944  fetchedVirtualAttributes << joinIt->targetField;
945  }
946  }
947 
948  if ( !mFetchJoinInfo.isEmpty() )
949  addJoinedAttributes( f );
950 
951  // add remaining expression fields
952  if ( !mExpressionFieldInfo.isEmpty() )
953  {
954  QMap<int, QgsExpression *>::ConstIterator it = mExpressionFieldInfo.constBegin();
955  for ( ; it != mExpressionFieldInfo.constEnd(); ++it )
956  {
957  if ( fetchedVirtualAttributes.contains( it.key() ) )
958  continue;
959 
960  addExpressionAttribute( f, it.key() );
961  }
962  }
963 }
964 
966 {
967  QgsExpression *exp = mExpressionFieldInfo.value( attrIndex );
968  if ( exp )
969  {
970  if ( !mExpressionContext )
971  createExpressionContext();
972 
973  mExpressionContext->setFeature( f );
974  QVariant val = exp->evaluate( mExpressionContext.get() );
975  ( void )mSource->mFields.at( attrIndex ).convertCompatible( val );
976  f.setAttribute( attrIndex, val );
977  }
978  else
979  {
980  f.setAttribute( attrIndex, QVariant() );
981  }
982 }
983 
985 {
986  Q_UNUSED( simplifyMethod )
987  return false;
988 }
989 
990 bool QgsVectorLayerFeatureIterator::providerCanSimplify( QgsSimplifyMethod::MethodType methodType ) const
991 {
992  Q_UNUSED( methodType )
993  return false;
994 }
995 
996 
998 {
999  const QHash<QString, QgsAttributes> &memoryCache = joinInfo->cachedAttributes;
1000  QHash<QString, QgsAttributes>::const_iterator it = memoryCache.find( joinValue.toString() );
1001  if ( it == memoryCache.constEnd() )
1002  return; // joined value not found -> leaving the attributes empty (null)
1003 
1004  int index = indexOffset;
1005 
1006  const QgsAttributes &featureAttributes = it.value();
1007  for ( int i = 0; i < featureAttributes.count(); ++i )
1008  {
1009  f.setAttribute( index++, featureAttributes.at( i ) );
1010  }
1011 }
1012 
1013 
1014 
1016 {
1017  // Shortcut
1018  if ( joinLayer && ! joinLayer->hasFeatures() )
1019  {
1020  return;
1021  }
1022 
1023  // no memory cache, query the joined values by setting substring
1024  QString subsetString;
1025 
1026  QString joinFieldName = joinInfo->joinFieldName();
1027 
1028  subsetString.append( QStringLiteral( "\"%1\"" ).arg( joinFieldName ) );
1029 
1030  if ( joinValue.isNull() )
1031  {
1032  subsetString += QLatin1String( " IS NULL" );
1033  }
1034  else
1035  {
1036  QString v = joinValue.toString();
1037  switch ( joinValue.type() )
1038  {
1039  case QVariant::Int:
1040  case QVariant::LongLong:
1041  case QVariant::Double:
1042  break;
1043 
1044  default:
1045  case QVariant::String:
1046  v.replace( '\'', QLatin1String( "''" ) );
1047  v.prepend( '\'' ).append( '\'' );
1048  break;
1049  }
1050  subsetString += '=' + v;
1051  }
1052 
1053  // maybe user requested just a subset of layer's attributes
1054  // so we do not have to cache everything
1055  QVector<int> subsetIndices;
1056  if ( joinInfo->hasSubset() )
1057  {
1058  const QStringList subsetNames = QgsVectorLayerJoinInfo::joinFieldNamesSubset( *joinInfo );
1059  subsetIndices = QgsVectorLayerJoinBuffer::joinSubsetIndices( joinLayer, subsetNames );
1060  }
1061 
1062  // select (no geometry)
1063  QgsFeatureRequest request;
1065  request.setSubsetOfAttributes( attributes );
1066  request.setFilterExpression( subsetString );
1067  request.setLimit( 1 );
1068  QgsFeatureIterator fi = joinLayer->getFeatures( request );
1069 
1070  // get first feature
1071  QgsFeature fet;
1072  if ( fi.nextFeature( fet ) )
1073  {
1074  int index = indexOffset;
1075  QgsAttributes attr = fet.attributes();
1076  if ( joinInfo->hasSubset() )
1077  {
1078  for ( int i = 0; i < subsetIndices.count(); ++i )
1079  f.setAttribute( index++, attr.at( subsetIndices.at( i ) ) );
1080  }
1081  else
1082  {
1083  // use all fields except for the one used for join (has same value as exiting field in target layer)
1084  for ( int i = 0; i < attr.count(); ++i )
1085  {
1086  if ( i == joinField )
1087  continue;
1088 
1089  f.setAttribute( index++, attr.at( i ) );
1090  }
1091  }
1092  }
1093  else
1094  {
1095  // no suitable join feature found, keeping empty (null) attributes
1096  }
1097 }
1098 
1099 
1100 
1101 
1103 {
1104  QgsFeatureId featureId = mRequest.filterFid();
1105 
1106  // deleted already?
1107  if ( mSource->mDeletedFeatureIds.contains( featureId ) )
1108  return false;
1109 
1110  // has changed geometry?
1111  if ( !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) && mSource->mChangedGeometries.contains( featureId ) )
1112  {
1113  useChangedAttributeFeature( featureId, mSource->mChangedGeometries[featureId], f );
1114  return true;
1115  }
1116 
1117  // added features
1118  for ( QgsFeatureMap::ConstIterator iter = mSource->mAddedFeatures.constBegin(); iter != mSource->mAddedFeatures.constEnd(); ++iter )
1119  {
1120  if ( iter->id() == featureId )
1121  {
1122  useAddedFeature( *iter, f );
1123  return true;
1124  }
1125  }
1126 
1127  // regular features
1129  if ( fi.nextFeature( f ) )
1130  {
1131  f.setFields( mSource->mFields );
1132 
1133  if ( mSource->mHasEditBuffer )
1135 
1136  if ( mHasVirtualAttributes )
1137  addVirtualAttributes( f );
1138 
1139  return true;
1140  }
1141 
1142  return false;
1143 }
1144 
1146 {
1147  QgsAttributes attrs = f.attributes();
1148 
1149  // remove all attributes that will disappear - from higher indices to lower
1150  for ( int idx = mSource->mDeletedAttributeIds.count() - 1; idx >= 0; --idx )
1151  {
1152  attrs.remove( mSource->mDeletedAttributeIds[idx] );
1153  }
1154 
1155  // adjust size to accommodate added attributes
1156  attrs.resize( attrs.count() + mSource->mAddedAttributes.count() );
1157 
1158  // update changed attributes
1159  if ( mSource->mChangedAttributeValues.contains( f.id() ) )
1160  {
1162  for ( QgsAttributeMap::const_iterator it = map.begin(); it != map.end(); ++it )
1163  attrs[it.key()] = it.value();
1164  }
1165  f.setAttributes( attrs );
1166 }
1167 
1169 {
1170  if ( mSource->mChangedGeometries.contains( f.id() ) )
1172 }
1173 
1174 void QgsVectorLayerFeatureIterator::createExpressionContext()
1175 {
1176  mExpressionContext = qgis::make_unique< QgsExpressionContext >();
1177  mExpressionContext->appendScope( QgsExpressionContextUtils::globalScope() );
1178  mExpressionContext->appendScope( QgsExpressionContextUtils::projectScope( QgsProject::instance() ) );
1179  mExpressionContext->appendScope( new QgsExpressionContextScope( mSource->mLayerScope ) );
1180 }
1181 
1182 bool QgsVectorLayerFeatureIterator::prepareOrderBy( const QList<QgsFeatureRequest::OrderByClause> &orderBys )
1183 {
1184  Q_UNUSED( orderBys )
1185  return true;
1186 }
1187 
1188 
1189 //
1190 // QgsVectorLayerSelectedFeatureSource
1191 //
1192 
1194  : mSource( layer )
1195  , mSelectedFeatureIds( layer->selectedFeatureIds() )
1196  , mWkbType( layer->wkbType() )
1197  , mName( layer->name() )
1198  , mLayer( layer )
1199 {}
1200 
1202 {
1203  QgsFeatureRequest req( request );
1204 
1205  // while QgsVectorLayerSelectedFeatureIterator will reject any features not in mSelectedFeatureIds,
1206  // we still tweak the feature request to only request selected feature ids wherever we can -- this
1207  // allows providers to optimise the request and avoid requesting features we don't need
1208  // note that we can't do this for some request types - e.g. expression based requests, so
1209  // in that case we just pass the request on to the provider and let QgsVectorLayerSelectedFeatureIterator
1210  // do ALL the filtering
1211  if ( req.filterFids().isEmpty() && req.filterType() == QgsFeatureRequest::FilterNone )
1212  {
1213  req.setFilterFids( mSelectedFeatureIds );
1214  }
1215  else if ( !req.filterFids().isEmpty() )
1216  {
1217  QgsFeatureIds reqIds = mSelectedFeatureIds;
1218  reqIds.intersect( req.filterFids() );
1219  req.setFilterFids( reqIds );
1220  }
1221 
1222  return QgsFeatureIterator( new QgsVectorLayerSelectedFeatureIterator( mSelectedFeatureIds, req, mSource ) );
1223 }
1224 
1226 {
1227  return mSource.crs();
1228 }
1229 
1231 {
1232  return mSource.fields();
1233 }
1234 
1236 {
1237  return mWkbType;
1238 }
1239 
1241 {
1242  return mSelectedFeatureIds.count();
1243 }
1244 
1246 {
1247  return mName;
1248 }
1249 
1251 {
1252  if ( mLayer )
1253  return mLayer->createExpressionContextScope();
1254  else
1255  return nullptr;
1256 }
1257 
1259 {
1260  if ( mLayer )
1261  return mLayer->hasSpatialIndex();
1262  else
1264 }
1265 
1266 //
1267 // QgsVectorLayerSelectedFeatureIterator
1268 //
1269 
1271 QgsVectorLayerSelectedFeatureIterator::QgsVectorLayerSelectedFeatureIterator( const QgsFeatureIds &selectedFeatureIds, const QgsFeatureRequest &request, QgsVectorLayerFeatureSource &source )
1272  : QgsAbstractFeatureIterator( request )
1273  , mSelectedFeatureIds( selectedFeatureIds )
1274 {
1275  QgsFeatureRequest sourceRequest = request;
1276  if ( sourceRequest.filterType() == QgsFeatureRequest::FilterExpression && sourceRequest.limit() > 0 )
1277  {
1278  // we can't pass the request limit to the provider here - otherwise the provider will
1279  // limit the number of returned features and may only return a bunch of matching features
1280  // which AREN'T in the selected feature set
1281  sourceRequest.setLimit( -1 );
1282  }
1283  mIterator = source.getFeatures( sourceRequest );
1284 }
1285 
1286 bool QgsVectorLayerSelectedFeatureIterator::rewind()
1287 {
1288  return mIterator.rewind();
1289 }
1290 
1291 bool QgsVectorLayerSelectedFeatureIterator::close()
1292 {
1293  return mIterator.close();
1294 }
1295 
1296 bool QgsVectorLayerSelectedFeatureIterator::fetchFeature( QgsFeature &f )
1297 {
1298  while ( mIterator.nextFeature( f ) )
1299  {
1300  if ( mSelectedFeatureIds.contains( f.id() ) )
1301  return true;
1302  }
1303  return false;
1304 }
1305 
QgsFields::OriginProvider
@ OriginProvider
Field comes from the underlying data provider of the vector layer (originIndex = index in provider's ...
Definition: qgsfields.h:51
QgsFeatureRequest::NoGeometry
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
Definition: qgsfeaturerequest.h:107
QgsVectorLayerFeatureIterator::fetchNextAddedFeature
bool fetchNextAddedFeature(QgsFeature &f)
Definition: qgsvectorlayerfeatureiterator.cpp:502
QgsFeatureRequest::invalidGeometryCallback
std::function< void(const QgsFeature &) > invalidGeometryCallback() const
Returns the callback function to use when encountering an invalid geometry and invalidGeometryCheck()...
Definition: qgsfeaturerequest.h:410
QgsMapLayer::crs
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:88
QgsVectorLayerFeatureSource::mLayerScope
QgsExpressionContextScope mLayerScope
Definition: qgsvectorlayerfeatureiterator.h:100
QgsVectorLayer::editBuffer
Q_INVOKABLE QgsVectorLayerEditBuffer * editBuffer()
Buffer with uncommitted editing operations. Only valid after editing has been turned on.
Definition: qgsvectorlayer.h:1942
QgsVectorLayerFeatureSource::getFeatures
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) override
Gets an iterator for features matching the specified request.
Definition: qgsvectorlayerfeatureiterator.cpp:96
QgsVectorLayerFeatureIterator::mChangedFeaturesIterator
QgsFeatureIterator mChangedFeaturesIterator
Definition: qgsvectorlayerfeatureiterator.h:234
qgsexpressioncontextutils.h
QgsVectorLayerFeatureIterator::setInterruptionChecker
void setInterruptionChecker(QgsFeedback *interruptionChecker) override
Attach an object that can be queried regularly by the iterator to check if it must stopped.
Definition: qgsvectorlayerfeatureiterator.cpp:491
QgsVectorLayerJoinBuffer::joinSubsetIndices
static QVector< int > joinSubsetIndices(QgsVectorLayer *joinLayer, const QStringList &joinFieldsSubset)
Returns a vector of indices for use in join based on field names from the layer.
Definition: qgsvectorlayerjoinbuffer.cpp:183
QgsFields::OriginEdit
@ OriginEdit
Field has been temporarily added in editing mode (originIndex = index in the list of added attributes...
Definition: qgsfields.h:53
QgsFeatureRequest::FilterFid
@ FilterFid
Filter using feature ID.
Definition: qgsfeaturerequest.h:106
QgsVectorLayerFeatureIterator::prepareJoin
void prepareJoin(int fieldIdx)
Definition: qgsvectorlayerfeatureiterator.cpp:657
QgsVectorLayerFeatureIterator::mFetchedFid
bool mFetchedFid
Definition: qgsvectorlayerfeatureiterator.h:244
QgsSimplifyMethod
Definition: qgssimplifymethod.h:28
QgsFeatureRequest::filterFids
const QgsFeatureIds & filterFids() const
Gets feature IDs that should be fetched.
Definition: qgsfeaturerequest.h:358
QgsVectorLayer::dataProvider
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
Definition: qgsvectorlayer.cpp:627
QgsFeatureRequest::GeometryAbortOnInvalid
@ GeometryAbortOnInvalid
Close iterator on encountering any features with invalid geometry. This requires a slow geometry vali...
Definition: qgsfeaturerequest.h:116
QgsVectorLayerFeatureIterator::FetchJoinInfo::addJoinedAttributesDirect
void addJoinedAttributesDirect(QgsFeature &f, const QVariant &joinValue) const
Definition: qgsvectorlayerfeatureiterator.cpp:1015
QgsFeatureRequest::transformContext
QgsCoordinateTransformContext transformContext() const
Returns the transform context, for use when a destinationCrs() has been set and reprojection is requi...
Definition: qgsfeaturerequest.cpp:258
QgsExpressionContextUtils::globalScope
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Definition: qgsexpressioncontextutils.cpp:33
QgsFeatureRequest::acceptFeature
bool acceptFeature(const QgsFeature &feature)
Check if a feature is accepted by this requests filter.
Definition: qgsfeaturerequest.cpp:276
QgsVectorLayerFeatureIterator::mTransform
QgsCoordinateTransform mTransform
Definition: qgsvectorlayerfeatureiterator.h:237
QgsExpression::referencedColumns
QSet< QString > referencedColumns() const
Gets list of columns referenced by the expression.
Definition: qgsexpression.cpp:217
QgsFeature::setId
void setId(QgsFeatureId id)
Sets the feature ID for this feature.
Definition: qgsfeature.cpp:112
QgsVectorLayerFeatureIterator::QgsVectorLayerFeatureIterator
QgsVectorLayerFeatureIterator(QgsVectorLayerFeatureSource *source, bool ownSource, const QgsFeatureRequest &request)
Definition: qgsvectorlayerfeatureiterator.cpp:118
QgsVectorLayerSelectedFeatureSource::sourceCrs
QgsCoordinateReferenceSystem sourceCrs() const override
Returns the coordinate reference system for features in the source.
Definition: qgsvectorlayerfeatureiterator.cpp:1225
qgsexpressionfieldbuffer.h
QgsVectorLayerFeatureSource::mFields
QgsFields mFields
Definition: qgsvectorlayerfeatureiterator.h:96
QgsVectorLayerFeatureIterator::addVirtualAttributes
void addVirtualAttributes(QgsFeature &f)
Adds attributes that don't source from the provider but are added inside QGIS Includes.
Definition: qgsvectorlayerfeatureiterator.cpp:925
QgsFeatureRequest::filterFid
QgsFeatureId filterFid() const
Gets the feature ID that should be fetched.
Definition: qgsfeaturerequest.h:353
QgsVectorLayerFeatureSource::mAddedFeatures
QgsFeatureMap mAddedFeatures
Definition: qgsvectorlayerfeatureiterator.h:107
QgsFeatureRequest::flags
const Flags & flags() const
Definition: qgsfeaturerequest.h:516
QgsFeatureRequest::filterRect
const QgsRectangle & filterRect() const
Returns the rectangle from which features will be taken.
Definition: qgsfeaturerequest.h:348
QgsAbstractFeatureIteratorFromSource< QgsVectorLayerFeatureSource >::iteratorClosed
void iteratorClosed()
to be called by from subclass in close()
Definition: qgsfeatureiterator.h:252
QgsVectorLayerFeatureIterator::mExpressionFieldInfo
QMap< int, QgsExpression * > mExpressionFieldInfo
Definition: qgsvectorlayerfeatureiterator.h:251
QgsFeatureRequest::filterType
FilterType filterType() const
Returns the filter type which is currently set on this request.
Definition: qgsfeaturerequest.h:325
QgsAbstractFeatureIterator::mClosed
bool mClosed
Sets to true, as soon as the iterator is closed.
Definition: qgsfeatureiterator.h:156
QgsFields::count
int count() const
Returns number of items.
Definition: qgsfields.cpp:133
QgsFields
Definition: qgsfields.h:44
QgsExpression::referencedAttributeIndexes
QSet< int > referencedAttributeIndexes(const QgsFields &fields) const
Returns a list of field name indexes obtained from the provided fields.
Definition: qgsexpression.cpp:241
QgsExpressionContextUtils::layerScope
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
Definition: qgsexpressioncontextutils.cpp:264
QgsVectorLayerFeatureSource::mDeletedAttributeIds
QgsAttributeList mDeletedAttributeIds
Definition: qgsvectorlayerfeatureiterator.h:112
QgsFeature::geometry
QgsGeometry geometry
Definition: qgsfeature.h:71
QgsProject::transformContext
QgsCoordinateTransformContext transformContext
Definition: qgsproject.h:99
QgsFeature::setValid
void setValid(bool validity)
Sets the validity of the feature.
Definition: qgsfeature.cpp:188
QgsVectorLayerFeatureSource::fields
QgsFields fields() const
Returns the fields that will be available for features that are retrieved from this source.
Definition: qgsvectorlayerfeatureiterator.cpp:102
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:458
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
QgsVectorLayerJoinInfo::joinFieldNamesSubset
QStringList * joinFieldNamesSubset() const
Returns the subset of fields to be used from joined layer.
Definition: qgsvectorlayerjoininfo.h:236
QgsAbstractFeatureIteratorFromSource< QgsVectorLayerFeatureSource >::mSource
QgsVectorLayerFeatureSource * mSource
Definition: qgsfeatureiterator.h:254
QgsVectorLayerFeatureSource::mChangedAttributeValues
QgsChangedAttributesMap mChangedAttributeValues
Definition: qgsvectorlayerfeatureiterator.h:111
QgsVectorLayerFeatureIterator::fetchNextChangedAttributeFeature
bool fetchNextChangedAttributeFeature(QgsFeature &f)
Definition: qgsvectorlayerfeatureiterator.cpp:585
QgsExpressionContext::setFields
void setFields(const QgsFields &fields)
Convenience function for setting a fields for the context.
Definition: qgsexpressioncontext.cpp:553
QgsWkbTypes::Type
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:68
QgsVectorLayerFeatureIterator::mProviderIterator
QgsFeatureIterator mProviderIterator
Definition: qgsvectorlayerfeatureiterator.h:232
QgsFeatureRequest::destinationCrs
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for feature's geometries, or an invalid QgsCoordi...
Definition: qgsfeaturerequest.cpp:253
QgsChangedAttributesMap
QMap< QgsFeatureId, QgsAttributeMap > QgsChangedAttributesMap
Definition: qgsfeature.h:558
QgsAbstractFeatureIterator::mRequest
QgsFeatureRequest mRequest
A copy of the feature request.
Definition: qgsfeatureiterator.h:153
QgsFeatureRequest::setSubsetOfAttributes
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
Definition: qgsfeaturerequest.cpp:190
QgsVectorLayerFeatureIterator::addExpressionAttribute
void addExpressionAttribute(QgsFeature &f, int attrIndex)
Adds an expression based attribute to a feature.
Definition: qgsvectorlayerfeatureiterator.cpp:965
QgsVectorLayerSelectedFeatureSource::sourceName
QString sourceName() const override
Returns a friendly display name for the source.
Definition: qgsvectorlayerfeatureiterator.cpp:1245
QgsFeatureIterator::isClosed
bool isClosed() const
find out whether the iterator is still valid or closed already
Definition: qgsfeatureiterator.h:394
QgsVectorLayerFeatureSource::mJoinBuffer
QgsVectorLayerJoinBuffer * mJoinBuffer
Definition: qgsvectorlayerfeatureiterator.h:92
QgsFeatureRequest::GeometrySkipInvalid
@ GeometrySkipInvalid
Skip any features with invalid geometry. This requires a slow geometry validity check for every featu...
Definition: qgsfeaturerequest.h:115
QgsVectorLayerFeatureIterator::addJoinedAttributes
void addJoinedAttributes(QgsFeature &f)
Definition: qgsvectorlayerfeatureiterator.cpp:908
QgsVectorLayerFeatureIterator::mFetchChangedGeomIt
QgsGeometryMap::ConstIterator mFetchChangedGeomIt
Definition: qgsvectorlayerfeatureiterator.h:241
QgsAttributeList
QList< int > QgsAttributeList
Definition: qgsfield.h:26
QgsField::name
QString name
Definition: qgsfield.h:59
QgsFeatureRequest::SubsetOfAttributes
@ SubsetOfAttributes
Fetch only a subset of attributes (setSubsetOfAttributes sets this flag)
Definition: qgsfeaturerequest.h:108
QgsFeatureRequest::disableFilter
QgsFeatureRequest & disableFilter()
Disables filter conditions.
Definition: qgsfeaturerequest.h:459
qgsgeometrysimplifier.h
QgsAbstractFeatureIteratorFromSource
Definition: qgsfeatureiterator.h:233
QgsFeatureRequest::setFilterFid
QgsFeatureRequest & setFilterFid(QgsFeatureId fid)
Sets feature ID that should be fetched.
Definition: qgsfeaturerequest.cpp:103
QgsFeatureRequest::expressionContext
QgsExpressionContext * expressionContext()
Returns the expression context used to evaluate filter expressions.
Definition: qgsfeaturerequest.h:441
QgsVectorLayerFeatureSource::mChangedGeometries
QgsGeometryMap mChangedGeometries
Definition: qgsvectorlayerfeatureiterator.h:108
QgsVectorLayerFeatureIterator::FetchJoinInfo::addJoinedAttributesCached
void addJoinedAttributesCached(QgsFeature &f, const QVariant &joinValue) const
Definition: qgsvectorlayerfeatureiterator.cpp:997
QgsVectorLayerJoinBuffer::joinedFieldsOffset
int joinedFieldsOffset(const QgsVectorLayerJoinInfo *info, const QgsFields &fields)
Find out what is the first index of the join within fields.
Definition: qgsvectorlayerjoinbuffer.cpp:377
QgsVectorLayerSelectedFeatureSource::QgsVectorLayerSelectedFeatureSource
QgsVectorLayerSelectedFeatureSource(QgsVectorLayer *layer)
Constructor for QgsVectorLayerSelectedFeatureSource, for selected features from the specified layer.
Definition: qgsvectorlayerfeatureiterator.cpp:1193
QgsFeatureRequest::setFilterExpression
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
Definition: qgsfeaturerequest.cpp:129
QgsFeatureRequest::setFilterRect
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
Definition: qgsfeaturerequest.cpp:97
QgsVectorLayerJoinInfo::targetFieldName
QString targetFieldName() const
Returns name of the field of our layer that will be used for join.
Definition: qgsvectorlayerjoininfo.h:68
QgsVectorLayer::fields
QgsFields fields() const FINAL
Returns the list of fields of this layer.
Definition: qgsvectorlayer.cpp:3280
QgsVectorLayerSelectedFeatureSource::wkbType
QgsWkbTypes::Type wkbType() const override
Returns the geometry type for features returned by this source.
Definition: qgsvectorlayerfeatureiterator.cpp:1235
QgsVectorLayerFeatureIterator::fetchFeature
bool fetchFeature(QgsFeature &feature) override
fetch next feature, return true on success
Definition: qgsvectorlayerfeatureiterator.cpp:351
QgsFeature::id
QgsFeatureId id
Definition: qgsfeature.h:68
QgsDistanceArea::setEllipsoid
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
Definition: qgsdistancearea.cpp:66
QgsAbstractFeatureIterator::filterRectToSourceCrs
QgsRectangle filterRectToSourceCrs(const QgsCoordinateTransform &transform) const SIP_THROW(QgsCsException)
Returns a rectangle representing the original request's QgsFeatureRequest::filterRect().
Definition: qgsfeatureiterator.cpp:118
QgsFeatureRequest
Definition: qgsfeaturerequest.h:75
QgsVectorLayerFeatureIterator::mChangedFeaturesRequest
QgsFeatureRequest mChangedFeaturesRequest
Definition: qgsvectorlayerfeatureiterator.h:233
QgsExpressionContextUtils::projectScope
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
Definition: qgsexpressioncontextutils.cpp:221
qgsexpressioncontext.h
QgsCsException
Definition: qgsexception.h:65
QgsVectorLayerFeatureIterator::FetchJoinInfo::joinField
int joinField
Index of field (of the joined layer) must have equal value.
Definition: qgsvectorlayerfeatureiterator.h:146
QgsVectorLayerFeatureIterator::prepareField
void prepareField(int fieldIdx)
Definition: qgsvectorlayerfeatureiterator.cpp:886
QgsVectorLayerFeatureIterator::prepareSimplification
bool prepareSimplification(const QgsSimplifyMethod &simplifyMethod) override
Setup the simplification of geometries to fetch using the specified simplify method.
Definition: qgsvectorlayerfeatureiterator.cpp:984
QgsVectorLayerFeatureIterator::FetchJoinInfo::joinLayer
QgsVectorLayer * joinLayer
Resolved pointer to the joined layer.
Definition: qgsvectorlayerfeatureiterator.h:144
QgsFeature::setGeometry
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:137
QgsVectorLayerSelectedFeatureSource::createExpressionContextScope
QgsExpressionContextScope * createExpressionContextScope() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
Definition: qgsvectorlayerfeatureiterator.cpp:1250
QgsVectorLayerEditBuffer::deletedAttributeIds
QgsAttributeList deletedAttributeIds() const
Returns a list of deleted attributes fields which are not committed.
Definition: qgsvectorlayereditbuffer.h:144
qgsvectorlayerjoinbuffer.h
QgsVectorLayerJoinInfo::cachedAttributes
QHash< QString, QgsAttributes > cachedAttributes
Cache for joined attributes to provide fast lookup (size is 0 if no memory caching)
Definition: qgsvectorlayerjoininfo.h:277
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:162
QgsFields::exists
bool exists(int i) const
Returns if a field index is valid.
Definition: qgsfields.cpp:153
QgsFeatureIterator::close
bool close()
Definition: qgsfeatureiterator.h:386
QgsVectorLayerSelectedFeatureSource::fields
QgsFields fields() const override
Returns the fields associated with features in the source.
Definition: qgsvectorlayerfeatureiterator.cpp:1230
QgsVectorDataProvider::featureSource
virtual QgsAbstractFeatureSource * featureSource() const =0
Returns feature source object that can be used for querying provider's data.
QgsFeedback
Definition: qgsfeedback.h:43
QgsFields::OriginUnknown
@ OriginUnknown
It has not been specified where the field comes from.
Definition: qgsfields.h:50
QgsVectorLayerFeatureSource::id
QString id() const
Returns the layer id of the source layer.
Definition: qgsvectorlayerfeatureiterator.cpp:112
QgsVectorLayerFeatureIterator::prepareFields
void prepareFields()
Definition: qgsvectorlayerfeatureiterator.cpp:752
QgsVectorLayerFeatureSource::mAddedAttributes
QList< QgsField > mAddedAttributes
Definition: qgsvectorlayerfeatureiterator.h:110
QgsVectorLayerEditBuffer::changedAttributeValues
QgsChangedAttributesMap changedAttributeValues() const
Returns a map of features with changed attributes values which are not committed.
Definition: qgsvectorlayereditbuffer.h:130
QgsFeatureSource::SpatialIndexPresence
SpatialIndexPresence
Enumeration of spatial index presence states.
Definition: qgsfeaturesource.h:187
QgsFeatureRequest::filterExpression
QgsExpression * filterExpression() const
Returns the filter expression if set.
Definition: qgsfeaturerequest.h:425
QgsVectorLayerJoinBuffer::clone
QgsVectorLayerJoinBuffer * clone() const
Create a copy of the join buffer.
Definition: qgsvectorlayerjoinbuffer.cpp:473
QgsField::convertCompatible
bool convertCompatible(QVariant &v) const
Converts the provided variant to a compatible format.
Definition: qgsfield.cpp:339
QgsVectorLayerFeatureIterator::updateFeatureGeometry
void updateFeatureGeometry(QgsFeature &f)
Update feature with uncommitted geometry updates.
Definition: qgsvectorlayerfeatureiterator.cpp:1168
QgsFields::fieldOrigin
FieldOrigin fieldOrigin(int fieldIdx) const
Gets field's origin (value from an enumeration)
Definition: qgsfields.cpp:189
qgsvectordataprovider.h
QgsVectorLayerFeatureIterator::updateChangedAttributes
void updateChangedAttributes(QgsFeature &f)
Update feature with uncommitted attribute updates.
Definition: qgsvectorlayerfeatureiterator.cpp:1145
QgsAttributeMap
QMap< int, QVariant > QgsAttributeMap
Definition: qgsattributes.h:38
QgsVectorLayerFeatureIterator::~QgsVectorLayerFeatureIterator
~QgsVectorLayerFeatureIterator() override
Definition: qgsvectorlayerfeatureiterator.cpp:282
QgsCoordinateReferenceSystem::isValid
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
Definition: qgscoordinatereferencesystem.cpp:902
QgsVectorLayerFeatureIterator::useAddedFeature
void useAddedFeature(const QgsFeature &src, QgsFeature &f)
Definition: qgsvectorlayerfeatureiterator.cpp:531
QgsVectorLayerJoinInfo::joinFieldName
QString joinFieldName() const
Returns name of the field of joined layer that will be used for join.
Definition: qgsvectorlayerjoininfo.h:73
QgsFeature::attribute
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:262
QgsMapLayer::id
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
Definition: qgsmaplayer.cpp:148
QgsFeatureRequest::setFilterFids
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Sets feature IDs that should be fetched.
Definition: qgsfeaturerequest.cpp:110
QgsVectorLayerJoinBuffer::createJoinCaches
void createJoinCaches()
Calls cacheJoinLayer() for all vector joins.
Definition: qgsvectorlayerjoinbuffer.cpp:254
qgsvectorlayerfeatureiterator.h
QgsVectorLayerFeatureIterator::nextFeatureFid
bool nextFeatureFid(QgsFeature &f)
Definition: qgsvectorlayerfeatureiterator.cpp:1102
QgsExpressionFieldBuffer::expressions
QList< QgsExpressionFieldBuffer::ExpressionField > expressions() const
Definition: qgsexpressionfieldbuffer.h:119
QgsVectorLayerFeatureIterator::prepareExpression
void prepareExpression(int fieldIdx)
Definition: qgsvectorlayerfeatureiterator.cpp:697
QgsVectorLayerJoinInfo
Definition: qgsvectorlayerjoininfo.h:33
QgsExpressionFieldBuffer
Definition: qgsexpressionfieldbuffer.h:35
QgsDistanceArea::setSourceCrs
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
Definition: qgsdistancearea.cpp:60
QgsFeatureRequest::FilterExpression
@ FilterExpression
Filter using expression.
Definition: qgsfeaturerequest.h:107
QgsFeatureMap
QMap< QgsFeatureId, QgsFeature > QgsFeatureMap
Definition: qgsvectorlayereditbuffer.h:30
QgsVectorLayerFeatureIterator::FetchJoinInfo::indexOffset
int indexOffset
At what position the joined fields start.
Definition: qgsvectorlayerfeatureiterator.h:143
QgsAbstractFeatureIterator::geometryToDestinationCrs
void geometryToDestinationCrs(QgsFeature &feature, const QgsCoordinateTransform &transform) const
Transforms feature's geometry according to the specified coordinate transform.
Definition: qgsfeatureiterator.cpp:95
QgsExpression::prepare
bool prepare(const QgsExpressionContext *context)
Gets the expression ready for evaluation - find out column indexes.
Definition: qgsexpression.cpp:323
QgsFeatureIds
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeatureid.h:34
QgsFeature::attributes
QgsAttributes attributes
Definition: qgsfeature.h:69
QgsCoordinateReferenceSystem
Definition: qgscoordinatereferencesystem.h:206
QgsVectorLayerFeatureSource::mCrs
QgsCoordinateReferenceSystem mCrs
Definition: qgsvectorlayerfeatureiterator.h:114
QgsExpression::evaluate
QVariant evaluate()
Evaluate the feature and return the result.
Definition: qgsexpression.cpp:346
QgsExpressionContextScope
Single scope for storing variables and functions for use within a QgsExpressionContext....
Definition: qgsexpressioncontext.h:111
QgsVectorLayerFeatureIterator::FetchJoinInfo::targetField
int targetField
Index of field (of this layer) that drives the join.
Definition: qgsvectorlayerfeatureiterator.h:145
QgsFeatureRequest::OrderBy::usedAttributeIndices
QSet< int > CORE_EXPORT usedAttributeIndices(const QgsFields &fields) const
Returns a set of used, validated attribute indices.
Definition: qgsfeaturerequest.cpp:501
QgsVectorLayerFeatureIterator::mFilterRect
QgsRectangle mFilterRect
Definition: qgsvectorlayerfeatureiterator.h:236
qgsvectorlayer.h
QgsVectorLayerFeatureIterator::mProviderRequest
QgsFeatureRequest mProviderRequest
Definition: qgsvectorlayerfeatureiterator.h:231
QgsVectorLayerFeatureIterator::FetchJoinInfo
Join information prepared for fast attribute id mapping in QgsVectorLayerJoinBuffer::updateFeatureAtt...
Definition: qgsvectorlayerfeatureiterator.h:139
QgsVectorLayerEditBuffer::deletedFeatureIds
QgsFeatureIds deletedFeatureIds() const
Returns a list of deleted feature IDs which are not committed.
Definition: qgsvectorlayereditbuffer.h:177
QgsVectorLayerFeatureSource::QgsVectorLayerFeatureIterator
friend class QgsVectorLayerFeatureIterator
Definition: qgsvectorlayerfeatureiterator.h:65
QgsFields::allAttributesList
QgsAttributeList allAttributesList() const
Utility function to get list of attribute indexes.
Definition: qgsfields.cpp:351
QgsFeature::setAttribute
bool setAttribute(int field, const QVariant &attr)
Set an attribute's value by field index.
Definition: qgsfeature.cpp:211
QgsVectorLayerFeatureIterator::rewind
bool rewind() override
reset the iterator to the starting position
Definition: qgsvectorlayerfeatureiterator.cpp:460
QgsFields::OriginExpression
@ OriginExpression
Field is calculated from an expression.
Definition: qgsfields.h:54
QgsVectorLayerFeatureSource::mExpressionFieldBuffer
QgsExpressionFieldBuffer * mExpressionFieldBuffer
Definition: qgsvectorlayerfeatureiterator.h:94
QgsVectorLayerFeatureSource::mHasEditBuffer
bool mHasEditBuffer
Definition: qgsvectorlayerfeatureiterator.h:102
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:373
QgsVectorLayerSelectedFeatureSource::featureCount
long featureCount() const override
Returns the number of features contained in the source, or -1 if the feature count is unknown.
Definition: qgsvectorlayerfeatureiterator.cpp:1240
QgsGeometry
Definition: qgsgeometry.h:122
QgsVectorLayerFeatureIterator::mHasVirtualAttributes
bool mHasVirtualAttributes
Definition: qgsvectorlayerfeatureiterator.h:253
QgsFeatureSource::SpatialIndexUnknown
@ SpatialIndexUnknown
Spatial index presence cannot be determined, index may or may not exist.
Definition: qgsfeaturesource.h:189
QgsFeatureRequest::invalidGeometryCheck
InvalidGeometryCheck invalidGeometryCheck() const
Returns the invalid geometry checking behavior.
Definition: qgsfeaturerequest.h:374
QgsFeatureRequest::orderBy
OrderBy orderBy() const
Returns a list of order by clauses specified for this feature request.
Definition: qgsfeaturerequest.cpp:167
QgsVectorLayer
Definition: qgsvectorlayer.h:385
QgsFeature::hasGeometry
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:197
QgsFeatureRequest::setLimit
QgsFeatureRequest & setLimit(long limit)
Set the maximum number of features to request.
Definition: qgsfeaturerequest.cpp:178
QgsVectorLayerFeatureIterator::mFetchConsidered
QSet< QgsFeatureId > mFetchConsidered
Definition: qgsvectorlayerfeatureiterator.h:240
QgsFeatureRequest::subsetOfAttributes
QgsAttributeList subsetOfAttributes() const
Returns the subset of attributes which at least need to be fetched.
Definition: qgsfeaturerequest.h:539
QgsVectorLayerFeatureSource
Definition: qgsvectorlayerfeatureiterator.h:51
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:58
QgsVectorLayerEditBuffer::changedGeometries
QgsGeometryMap changedGeometries() const
Returns a map of features with changed geometries which are not committed.
Definition: qgsvectorlayereditbuffer.h:163
QgsMessageLog::logMessage
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Definition: qgsmessagelog.cpp:27
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
QgsVectorLayerFeatureSource::QgsVectorLayerFeatureSource
QgsVectorLayerFeatureSource(const QgsVectorLayer *layer)
Constructor for QgsVectorLayerFeatureSource.
Definition: qgsvectorlayerfeatureiterator.cpp:31
QgsFeatureRequest::GeometryNoCheck
@ GeometryNoCheck
No invalid geometry checking.
Definition: qgsfeaturerequest.h:114
QgsVectorLayerJoinBuffer::containsJoins
bool containsJoins() const
Quick way to test if there is any join at all.
Definition: qgsvectorlayerjoinbuffer.h:80
QgsVectorLayerFeatureIterator::useChangedAttributeFeature
void useChangedAttributeFeature(QgsFeatureId fid, const QgsGeometry &geom, QgsFeature &f)
Definition: qgsvectorlayerfeatureiterator.cpp:611
QgsExpression::needsGeometry
bool needsGeometry() const
Returns true if the expression uses feature geometry for some computation.
Definition: qgsexpression.cpp:266
Qgis::Critical
@ Critical
Definition: qgis.h:105
QgsDistanceArea
Definition: qgsdistancearea.h:49
QgsAttributes
Definition: qgsattributes.h:57
QgsVectorLayerFeatureSource::~QgsVectorLayerFeatureSource
~QgsVectorLayerFeatureSource() override
Definition: qgsvectorlayerfeatureiterator.cpp:89
QgsFeatureRequest::FilterNone
@ FilterNone
No filter is applied.
Definition: qgsfeaturerequest.h:105
QgsSimplifyMethod::MethodType
MethodType
Definition: qgssimplifymethod.h:31
QgsVectorLayerFeatureIterator::close
bool close() override
end of iterating: free the resources / lock
Definition: qgsvectorlayerfeatureiterator.cpp:478
QgsAbstractFeatureSource::getFeatures
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())=0
Gets an iterator for features matching the specified request.
QgsGeometryMap
QMap< QgsFeatureId, QgsGeometry > QgsGeometryMap
Definition: qgsfeature.h:567
qgsexception.h
qgsdistancearea.h
QgsFeature
Definition: qgsfeature.h:55
QgsFeatureIterator::setInterruptionChecker
void setInterruptionChecker(QgsFeedback *interruptionChecker)
Attach an object that can be queried regularly by the iterator to check if it must stopped.
Definition: qgsfeatureiterator.h:409
QgsVectorLayerFeatureIterator::isValid
bool isValid() const override
Returns if this iterator is valid.
Definition: qgsvectorlayerfeatureiterator.cpp:497
QgsVectorLayerFeatureSource::mProviderFeatureSource
QgsAbstractFeatureSource * mProviderFeatureSource
Definition: qgsvectorlayerfeatureiterator.h:90
QgsVectorLayerFeatureSource::crs
QgsCoordinateReferenceSystem crs() const
Returns the coordinate reference system for features retrieved from this source.
Definition: qgsvectorlayerfeatureiterator.cpp:107
QgsFeatureRequest::setDestinationCrs
QgsFeatureRequest & setDestinationCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets the destination crs for feature's geometries.
Definition: qgsfeaturerequest.cpp:263
QgsVectorLayerSelectedFeatureSource::getFeatures
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const override
Returns an iterator for the features in the source.
Definition: qgsvectorlayerfeatureiterator.cpp:1201
QgsGeometry::isGeosValid
bool isGeosValid(QgsGeometry::ValidityFlags flags=QgsGeometry::ValidityFlags()) const
Checks validity of the geometry using GEOS.
Definition: qgsgeometry.cpp:2734
QgsVectorLayerSelectedFeatureSource::hasSpatialIndex
SpatialIndexPresence hasSpatialIndex() const override
Returns an enum value representing the presence of a valid spatial index on the source,...
Definition: qgsvectorlayerfeatureiterator.cpp:1258
QgsVectorLayerFeatureIterator::FetchJoinInfo::joinInfo
const QgsVectorLayerJoinInfo * joinInfo
Canonical source of information about the join.
Definition: qgsvectorlayerfeatureiterator.h:141
QgsFeature::setAttributes
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
Definition: qgsfeature.cpp:127
QgsFields::lookupField
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
Definition: qgsfields.cpp:324
QgsFields::at
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
Definition: qgsfields.cpp:163
QgsVectorLayerEditBuffer::addedAttributes
QList< QgsField > addedAttributes() const
Returns a list of added attributes fields which are not committed.
Definition: qgsvectorlayereditbuffer.h:157
QgsExpression
Definition: qgsexpression.h:113
QgsCoordinateTransform
Definition: qgscoordinatetransform.h:52
QgsFeatureIterator
Definition: qgsfeatureiterator.h:263
QgsVectorLayerFeatureSource::mId
QString mId
Definition: qgsvectorlayerfeatureiterator.h:98
QgsVectorLayerFeatureIterator::rewindEditBuffer
void rewindEditBuffer()
Definition: qgsvectorlayerfeatureiterator.cpp:649
QgsFeatureRequest::setFlags
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched.
Definition: qgsfeaturerequest.cpp:184
attributeIndexes
const QgsAttributeList & attributeIndexes
Definition: qgswfsgetfeature.cpp:107
QgsVectorLayerFeatureIterator::fetchNextChangedGeomFeature
bool fetchNextChangedGeomFeature(QgsFeature &f)
Definition: qgsvectorlayerfeatureiterator.cpp:546
QgsAbstractFeatureIterator
Definition: qgsfeatureiterator.h:28
QgsVectorLayerFeatureSource::mDeletedFeatureIds
QgsFeatureIds mDeletedFeatureIds
Definition: qgsvectorlayerfeatureiterator.h:109
QgsVectorLayerFeatureIterator::mFetchJoinInfo
QMap< const QgsVectorLayerJoinInfo *, QgsVectorLayerFeatureIterator::FetchJoinInfo > mFetchJoinInfo
Information about joins used in the current select() statement.
Definition: qgsvectorlayerfeatureiterator.h:249
QgsVectorLayerEditBuffer::addedFeatures
QgsFeatureMap addedFeatures() const
Returns a map of new features which are not committed.
Definition: qgsvectorlayereditbuffer.h:116
QgsRectangle::isNull
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
Definition: qgsrectangle.h:447
QgsFeatureIterator::rewind
bool rewind()
Definition: qgsfeatureiterator.h:378
qgsproject.h
QgsFeatureIterator::isValid
bool isValid() const
Will return if this iterator is valid.
Definition: qgsfeatureiterator.cpp:239
QgsFields::indexFromName
int indexFromName(const QString &fieldName) const
Gets the field index from the field name.
Definition: qgsfields.cpp:202
qgsvectorlayereditbuffer.h
QgsVectorLayerFeatureIterator::mFetchAddedFeaturesIt
QgsFeatureMap::ConstIterator mFetchAddedFeaturesIt
Definition: qgsvectorlayerfeatureiterator.h:242
QgsFields::OriginJoin
@ OriginJoin
Field comes from a joined layer (originIndex / 1000 = index of the join, originIndex % 1000 = index w...
Definition: qgsfields.h:52
qgssimplifymethod.h
QgsFeatureId
qint64 QgsFeatureId
Definition: qgsfeatureid.h:25
qgsmessagelog.h
QgsExpressionContext::setFeature
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
Definition: qgsexpressioncontext.cpp:521
QgsFeatureRequest::limit
long limit() const
Returns the maximum number of features to request, or -1 if no limit set.
Definition: qgsfeaturerequest.h:512