QGIS API Documentation
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 "qgsmaplayerregistry.h"
20 #include "qgssimplifymethod.h"
21 #include "qgsvectordataprovider.h"
23 #include "qgsvectorlayer.h"
25 #include "qgsexpressioncontext.h"
26 #include "qgsdistancearea.h"
27 #include "qgsproject.h"
28 
30  : mCrsId( 0 )
31 {
33  mFields = layer->fields();
34  mJoinBuffer = layer->mJoinBuffer->clone();
35  mExpressionFieldBuffer = new QgsExpressionFieldBuffer( *layer->mExpressionFieldBuffer );
36  mCrsId = layer->crs().srsid();
37 
38  mCanBeSimplified = layer->hasGeometryType() && layer->geometryType() != QGis::Point;
39 
40  mHasEditBuffer = layer->editBuffer();
41  if ( mHasEditBuffer )
42  {
43 #if 0
44  // TODO[MD]: after merge
45  if ( request.filterType() == QgsFeatureRequest::FilterFid )
46  {
47 
48  // only copy relevant parts
49  if ( L->editBuffer()->addedFeatures().contains( request.filterFid() ) )
50  mAddedFeatures.insert( request.filterFid(), L->editBuffer()->addedFeatures()[ request.filterFid()] );
51 
52  if ( L->editBuffer()->changedGeometries().contains( request.filterFid() ) )
53  mChangedGeometries.insert( request.filterFid(), L->editBuffer()->changedGeometries()[ request.filterFid()] );
54 
55  if ( L->editBuffer()->deletedFeatureIds().contains( request.filterFid() ) )
56  mDeletedFeatureIds.insert( request.filterFid() );
57 
58  if ( L->editBuffer()->changedAttributeValues().contains( request.filterFid() ) )
59  mChangedAttributeValues.insert( request.filterFid(), L->editBuffer()->changedAttributeValues()[ request.filterFid()] );
60 
61  if ( L->editBuffer()->changedAttributeValues().contains( request.filterFid() ) )
62  mChangedFeaturesRequest.setFilterFids( QgsFeatureIds() << request.filterFid() );
63  }
64  else
65  {
66 #endif
73 #if 0
74  }
75 #endif
76  }
77 }
78 
80 {
81  delete mJoinBuffer;
84 }
85 
87 {
88  // return feature iterator that does not own this source
89  return QgsFeatureIterator( new QgsVectorLayerFeatureIterator( this, false, request ) );
90 }
91 
92 
95  , mFetchedFid( false )
96  , mEditGeometrySimplifier( nullptr )
97  , mInterruptionChecker( nullptr )
98 {
100 
101  // prepare joins: may add more attributes to fetch (in order to allow join)
103  prepareJoins();
104 
106 
107  // by default provider's request is the same
109 
111  {
112  // prepare list of attributes to match provider fields
113  QSet<int> providerSubset;
115  int nPendingFields = mSource->mFields.count();
116  Q_FOREACH ( int attrIndex, subset )
117  {
118  if ( attrIndex < 0 || attrIndex >= nPendingFields ) continue;
119  if ( mSource->mFields.fieldOrigin( attrIndex ) == QgsFields::OriginProvider )
120  providerSubset << mSource->mFields.fieldOriginIndex( attrIndex );
121  }
122 
123  // This is done in order to be prepared to do fallback order bys
124  // and be sure we have the required columns.
125  // TODO:
126  // It would be nicer to first check if we can compile the order by
127  // and only modify the subset if we cannot.
128  if ( !mProviderRequest.orderBy().isEmpty() )
129  {
130  Q_FOREACH ( const QString& attr, mProviderRequest.orderBy().usedAttributes() )
131  {
132  providerSubset << mSource->mFields.fieldNameIndex( attr );
133  }
134  }
135 
136  mProviderRequest.setSubsetOfAttributes( providerSubset.toList() );
137  }
138 
140  {
141  Q_FOREACH ( const QString& field, mProviderRequest.filterExpression()->referencedColumns() )
142  {
143  int idx = source->mFields.fieldNameIndex( field );
144 
145  // If there are fields in the expression which are not of origin provider, the provider will not be able to filter based on them.
146  // In this case we disable the expression filter.
147  if ( source->mFields.fieldOrigin( idx ) != QgsFields::OriginProvider )
148  {
150  }
151  }
152  }
153 
154  if ( mSource->mHasEditBuffer )
155  {
158  }
159 
160  if ( request.filterType() == QgsFeatureRequest::FilterFid )
161  {
162  mFetchedFid = false;
163  }
164  else // no filter or filter by rect
165  {
166  if ( mSource->mHasEditBuffer )
167  {
169  }
170  else
171  {
173  }
174 
176  }
177 
179  {
182  }
183 }
184 
185 
187 {
188  delete mEditGeometrySimplifier;
189  mEditGeometrySimplifier = nullptr;
190 
191  qDeleteAll( mExpressionFieldInfo );
192 
193  close();
194 }
195 
196 
197 
199 {
200  f.setValid( false );
201 
202  if ( mClosed )
203  return false;
204 
206  {
207  if ( mFetchedFid )
208  return false;
209  bool res = nextFeatureFid( f );
210  mFetchedFid = true;
211  return res;
212  }
213 
214  if ( !mRequest.filterRect().isNull() )
215  {
216  if ( fetchNextChangedGeomFeature( f ) )
217  return true;
218 
219  // no more changed geometries
220  }
221 
223  {
225  return true;
226 
227  // no more changed features
228  }
229 
230  while ( fetchNextAddedFeature( f ) )
231  {
232  return true;
233  }
234  // no more added features
235 
236  if ( mProviderIterator.isClosed() )
237  {
240  mProviderIterator.setInterruptionChecker( mInterruptionChecker );
241  }
242 
243  while ( mProviderIterator.nextFeature( f ) )
244  {
245  if ( mFetchConsidered.contains( f.id() ) )
246  continue;
247 
248  // TODO[MD]: just one resize of attributes
249  f.setFields( mSource->mFields );
250 
251  // update attributes
252  if ( mSource->mHasEditBuffer )
254 
255  if ( mHasVirtualAttributes )
257 
259  {
260  //filtering by expression, and couldn't do it on the provider side
263  {
264  //feature did not match filter
265  continue;
266  }
267  }
268 
269  // update geometry
270  // TODO[MK]: FilterRect check after updating the geometry
273 
274  return true;
275  }
276  // no more provider features
277 
278  close();
279  return false;
280 }
281 
282 
283 
285 {
286  if ( mClosed )
287  return false;
288 
290  {
291  mFetchedFid = false;
292  }
293  else
294  {
297  }
298 
299  return true;
300 }
301 
303 {
304  if ( mClosed )
305  return false;
306 
308 
309  iteratorClosed();
310 
311  mClosed = true;
312  return true;
313 }
314 
316 {
317  mProviderIterator.setInterruptionChecker( interruptionChecker );
318  mInterruptionChecker = interruptionChecker;
319 }
320 
322 {
324  {
326 
327  if ( mFetchConsidered.contains( fid ) )
328  // must have changed geometry outside rectangle
329  continue;
330 
332  // skip features which are not accepted by the filter
333  continue;
334 
336 
337  return true;
338  }
339 
341  return false; // no more added features
342 }
343 
344 
346 {
347  f.setFeatureId( src.id() );
348  f.setValid( true );
349  f.setFields( mSource->mFields );
350 
352  {
353  f.setGeometry( new QgsGeometry( *src.constGeometry() ) );
354 
355  // simplify the edited geometry using its simplifier configured
356  if ( mEditGeometrySimplifier )
357  {
358  QgsGeometry* geometry = f.geometry();
359  QGis::GeometryType geometryType = geometry->type();
360  if ( geometryType == QGis::Line || geometryType == QGis::Polygon ) mEditGeometrySimplifier->simplifyGeometry( geometry );
361  }
362  }
363 
364  // TODO[MD]: if subset set just some attributes
365 
366  f.setAttributes( src.attributes() );
367 
368  if ( mHasVirtualAttributes )
370 }
371 
372 
373 
375 {
376  // check if changed geometries are in rectangle
378  {
379  QgsFeatureId fid = mFetchChangedGeomIt.key();
380 
381  if ( mFetchConsidered.contains( fid ) )
382  // skip deleted features
383  continue;
384 
385  mFetchConsidered << fid;
386 
387  if ( !mFetchChangedGeomIt->intersects( mRequest.filterRect() ) )
388  // skip changed geometries not in rectangle and don't check again
389  continue;
390 
392 
393  // return complete feature
395  return true;
396  }
397 
398  return false; // no more changed geometries
399 }
400 
402 {
404  {
405  if ( mFetchConsidered.contains( f.id() ) )
406  // skip deleted features and those already handled by the geometry
407  continue;
408 
409  mFetchConsidered << f.id();
410 
412 
413  if ( mHasVirtualAttributes )
415 
418  {
419  return true;
420  }
421  }
422 
423  return false;
424 }
425 
426 
428 {
429  f.setFeatureId( fid );
430  f.setValid( true );
431  f.setFields( mSource->mFields );
432 
434  {
435  f.setGeometry( geom );
436 
437  // simplify the edited geometry using its simplifier configured
438  if ( mEditGeometrySimplifier )
439  {
440  QgsGeometry* geometry = f.geometry();
441  QGis::GeometryType geometryType = geometry->type();
442  if ( geometryType == QGis::Line || geometryType == QGis::Polygon ) mEditGeometrySimplifier->simplifyGeometry( geometry );
443  }
444  }
445 
446  bool subsetAttrs = ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes );
447  if ( !subsetAttrs || !mRequest.subsetOfAttributes().isEmpty() )
448  {
449  // retrieve attributes from provider
450  QgsFeature tmp;
451  //mDataProvider->featureAtId( fid, tmp, false, mFetchProvAttributes );
452  QgsFeatureRequest request;
454  if ( subsetAttrs )
455  {
457  }
459  if ( fi.nextFeature( tmp ) )
460  {
463  f.setAttributes( tmp.attributes() );
464  }
465  }
466 
468 }
469 
470 
471 
473 {
475 
478 }
479 
480 
481 
483 {
485  QgsAttributeList sourceJoinFields; // attributes that also need to be fetched from this layer in order to have joins working
486 
487  mFetchJoinInfo.clear();
488 
489  for ( QgsAttributeList::const_iterator attIt = fetchAttributes.constBegin(); attIt != fetchAttributes.constEnd(); ++attIt )
490  {
491  if ( !mSource->mFields.exists( *attIt ) )
492  continue;
493 
494  if ( mSource->mFields.fieldOrigin( *attIt ) != QgsFields::OriginJoin )
495  continue;
496 
497  int sourceLayerIndex;
498  const QgsVectorJoinInfo* joinInfo = mSource->mJoinBuffer->joinForFieldIndex( *attIt, mSource->mFields, sourceLayerIndex );
499  Q_ASSERT( joinInfo );
500 
501  QgsVectorLayer* joinLayer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( joinInfo->joinLayerId ) );
502  Q_ASSERT( joinLayer );
503 
504  if ( !mFetchJoinInfo.contains( joinInfo ) )
505  {
506  FetchJoinInfo info;
507  info.joinInfo = joinInfo;
508  info.joinLayer = joinLayer;
510 
511  if ( joinInfo->targetFieldName.isEmpty() )
512  info.targetField = joinInfo->targetFieldIndex; //for compatibility with 1.x
513  else
515 
516  if ( joinInfo->joinFieldName.isEmpty() )
517  info.joinField = joinInfo->joinFieldIndex; //for compatibility with 1.x
518  else
519  info.joinField = joinLayer->fields().indexFromName( joinInfo->joinFieldName );
520 
521  // for joined fields, we always need to request the targetField from the provider too
522  if ( !fetchAttributes.contains( info.targetField ) )
523  sourceJoinFields << info.targetField;
524 
525  mFetchJoinInfo.insert( joinInfo, info );
526  }
527 
528  // store field source index - we'll need it when fetching from provider
529  mFetchJoinInfo[ joinInfo ].attributes.push_back( sourceLayerIndex );
530  }
531 
532  // add sourceJoinFields if we're using a subset
535 }
536 
538 {
540 
541  mExpressionContext.reset( new QgsExpressionContext() );
542  mExpressionContext->appendScope( QgsExpressionContextUtils::globalScope() );
543  mExpressionContext->appendScope( QgsExpressionContextUtils::projectScope() );
544  mExpressionContext->setFields( mSource->mFields );
545 
546  for ( int i = 0; i < mSource->mFields.count(); i++ )
547  {
549  {
550  // Only prepare if there is no subset defined or the subset contains this field
553  {
554  int oi = mSource->mFields.fieldOriginIndex( i );
555  QgsExpression* exp = new QgsExpression( exps[oi].cachedExpression );
556 
557  QgsDistanceArea da;
558  da.setSourceCrs( mSource->mCrsId );
559  da.setEllipsoidalMode( true );
560  da.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
561  exp->setGeomCalculator( da );
562  exp->setDistanceUnits( QgsProject::instance()->distanceUnits() );
563  exp->setAreaUnits( QgsProject::instance()->areaUnits() );
564 
565  exp->prepare( mExpressionContext.data() );
566  mExpressionFieldInfo.insert( i, exp );
567 
569  {
570  QgsAttributeList attrs;
571  Q_FOREACH ( const QString& col, exp->referencedColumns() )
572  {
573  attrs.append( mSource->mFields.fieldNameIndex( col ) );
574  }
575 
577  }
578 
579  if ( exp->needsGeometry() )
580  {
581  mRequest.setFlags( mRequest.flags() & ~QgsFeatureRequest::NoGeometry );
582  }
583  }
584  }
585  }
586 }
587 
589 {
591  for ( ; joinIt != mFetchJoinInfo.constEnd(); ++joinIt )
592  {
593  const FetchJoinInfo& info = joinIt.value();
594  Q_ASSERT( joinIt.key() );
595 
596  QVariant targetFieldValue = f.attribute( info.targetField );
597  if ( !targetFieldValue.isValid() )
598  continue;
599 
600  const QHash< QString, QgsAttributes>& memoryCache = info.joinInfo->cachedAttributes;
601  if ( memoryCache.isEmpty() )
602  info.addJoinedAttributesDirect( f, targetFieldValue );
603  else
604  info.addJoinedAttributesCached( f, targetFieldValue );
605  }
606 }
607 
609 {
610  // make sure we have space for newly added attributes
611  QgsAttributes attr = f.attributes();
612  attr.resize( mSource->mFields.count() ); // Provider attrs count + joined attrs count + expression attrs count
613  f.setAttributes( attr );
614 
615  if ( !mFetchJoinInfo.isEmpty() )
616  addJoinedAttributes( f );
617 
618  if ( !mExpressionFieldInfo.isEmpty() )
619  {
621 
622  for ( ; it != mExpressionFieldInfo.constEnd(); ++it )
623  {
624  QgsExpression* exp = it.value();
625  mExpressionContext->setFeature( f );
626  QVariant val = exp->evaluate( mExpressionContext.data() );
627  mSource->mFields.at( it.key() ).convertCompatible( val );
628  f.setAttribute( it.key(), val );
629  }
630  }
631 }
632 
634 {
635  delete mEditGeometrySimplifier;
636  mEditGeometrySimplifier = nullptr;
637 
638  // setup simplification for edited geometries to fetch
640  {
641  mEditGeometrySimplifier = QgsSimplifyMethod::createGeometrySimplifier( simplifyMethod );
642  return nullptr != mEditGeometrySimplifier;
643  }
644  return false;
645 }
646 
647 bool QgsVectorLayerFeatureIterator::providerCanSimplify( QgsSimplifyMethod::MethodType methodType ) const
648 {
649  Q_UNUSED( methodType );
650 #if 0
651  // TODO[MD]: after merge
652  QgsVectorDataProvider* provider = L->dataProvider();
653 
654  if ( provider && methodType != QgsSimplifyMethod::NoSimplification )
655  {
656  int capabilities = provider->capabilities();
657 
658  if ( methodType == QgsSimplifyMethod::OptimizeForRendering )
659  {
660  return ( capabilities & QgsVectorDataProvider::SimplifyGeometries );
661  }
662  else if ( methodType == QgsSimplifyMethod::PreserveTopology )
663  {
665  }
666  }
667 #endif
668  return false;
669 }
670 
671 
673 {
674  const QHash<QString, QgsAttributes>& memoryCache = joinInfo->cachedAttributes;
675  QHash<QString, QgsAttributes>::const_iterator it = memoryCache.find( joinValue.toString() );
676  if ( it == memoryCache.constEnd() )
677  return; // joined value not found -> leaving the attributes empty (null)
678 
679  int index = indexOffset;
680 
681  const QgsAttributes& featureAttributes = it.value();
682  for ( int i = 0; i < featureAttributes.count(); ++i )
683  {
684  f.setAttribute( index++, featureAttributes.at( i ) );
685  }
686 }
687 
688 
689 
691 {
692  // no memory cache, query the joined values by setting substring
693  QString subsetString = joinLayer->dataProvider()->subsetString(); // provider might already have a subset string
694  QString bkSubsetString = subsetString;
695  if ( !subsetString.isEmpty() )
696  {
697  subsetString.prepend( '(' ).append( ") AND " );
698  }
699 
700  QString joinFieldName;
701  if ( joinInfo->joinFieldName.isEmpty() && joinInfo->joinFieldIndex >= 0 && joinInfo->joinFieldIndex < joinLayer->fields().count() )
702  joinFieldName = joinLayer->fields().field( joinInfo->joinFieldIndex ).name(); // for compatibility with 1.x
703  else
704  joinFieldName = joinInfo->joinFieldName;
705 
706  subsetString.append( QString( "\"%1\"" ).arg( joinFieldName ) );
707 
708  if ( joinValue.isNull() )
709  {
710  subsetString += " IS NULL";
711  }
712  else
713  {
714  QString v = joinValue.toString();
715  switch ( joinValue.type() )
716  {
717  case QVariant::Int:
718  case QVariant::LongLong:
719  case QVariant::Double:
720  break;
721 
722  default:
723  case QVariant::String:
724  v.replace( '\'', "''" );
725  v.prepend( '\'' ).append( '\'' );
726  break;
727  }
728  subsetString += '=' + v;
729  }
730 
731  joinLayer->dataProvider()->setSubsetString( subsetString, false );
732 
733  // maybe user requested just a subset of layer's attributes
734  // so we do not have to cache everything
735  bool hasSubset = joinInfo->joinFieldNamesSubset();
736  QVector<int> subsetIndices;
737  if ( hasSubset )
738  subsetIndices = QgsVectorLayerJoinBuffer::joinSubsetIndices( joinLayer, *joinInfo->joinFieldNamesSubset() );
739 
740  // select (no geometry)
741  QgsFeatureRequest request;
743  request.setSubsetOfAttributes( attributes );
744  QgsFeatureIterator fi = joinLayer->getFeatures( request );
745 
746  // get first feature
747  QgsFeature fet;
748  if ( fi.nextFeature( fet ) )
749  {
750  int index = indexOffset;
751  QgsAttributes attr = fet.attributes();
752  if ( hasSubset )
753  {
754  for ( int i = 0; i < subsetIndices.count(); ++i )
755  f.setAttribute( index++, attr.at( subsetIndices.at( i ) ) );
756  }
757  else
758  {
759  // use all fields except for the one used for join (has same value as exiting field in target layer)
760  for ( int i = 0; i < attr.count(); ++i )
761  {
762  if ( i == joinField )
763  continue;
764 
765  f.setAttribute( index++, attr.at( i ) );
766  }
767  }
768  }
769  else
770  {
771  // no suitable join feature found, keeping empty (null) attributes
772  }
773 
774  joinLayer->dataProvider()->setSubsetString( bkSubsetString, false );
775 }
776 
777 
778 
779 
781 {
782  QgsFeatureId featureId = mRequest.filterFid();
783 
784  // deleted already?
785  if ( mSource->mDeletedFeatureIds.contains( featureId ) )
786  return false;
787 
788  // has changed geometry?
790  {
791  useChangedAttributeFeature( featureId, mSource->mChangedGeometries[featureId], f );
792  return true;
793  }
794 
795  // added features
797  {
798  if ( iter->id() == featureId )
799  {
800  useAddedFeature( *iter, f );
801  return true;
802  }
803  }
804 
805  // regular features
807  if ( fi.nextFeature( f ) )
808  {
809  if ( mSource->mHasEditBuffer )
811 
812  if ( mHasVirtualAttributes )
814 
815  return true;
816  }
817 
818  return false;
819 }
820 
822 {
823  QgsAttributes attrs = f.attributes();
824 
825  // remove all attributes that will disappear - from higher indices to lower
826  for ( int idx = mSource->mDeletedAttributeIds.count() - 1; idx >= 0; --idx )
827  {
828  attrs.remove( mSource->mDeletedAttributeIds[idx] );
829  }
830 
831  // adjust size to accommodate added attributes
832  attrs.resize( attrs.count() + mSource->mAddedAttributes.count() );
833 
834  // update changed attributes
836  {
838  for ( QgsAttributeMap::const_iterator it = map.begin(); it != map.end(); ++it )
839  attrs[it.key()] = it.value();
840  }
841  f.setAttributes( attrs );
842 }
843 
845 {
846  if ( mSource->mChangedGeometries.contains( f.id() ) )
848 }
849 
850 bool QgsVectorLayerFeatureIterator::prepareOrderBy( const QList<QgsFeatureRequest::OrderByClause>& orderBys )
851 {
852  Q_UNUSED( orderBys );
853  return true;
854 }
855 
QgsFeatureId id() const
Get the feature ID for this feature.
Definition: qgsfeature.cpp:65
void setAreaUnits(QgsUnitTypes::AreaUnit unit)
Sets the desired areal units for calculations involving geomCalculator(), eg "$area".
const QgsGeometryMap & changedGeometries()
Changed geometries which are not commited.
QgsAbstractFeatureSource * mProviderFeatureSource
Class for parsing and evaluation of expressions (formerly called "search strings").
Wrapper for iterator of features from vector data provider or vector layer.
void addJoinedAttributesDirect(QgsFeature &f, const QVariant &joinValue) const
QMap< QgsFeatureId, QgsGeometry > QgsGeometryMap
Definition: qgsfeature.h:431
static unsigned index
bool acceptFeature(const QgsFeature &feature)
Check if a feature is accepted by this requests filter.
QString & append(QChar ch)
Filter using feature ID.
QgsVectorLayerJoinBuffer * mJoinBuffer
const Flags & flags() const
QString joinFieldName
Join field in the source layer.
field comes from a joined layer (originIndex / 1000 = index of the join, originIndex % 1000 = index w...
Definition: qgsfield.h:195
virtual void setInterruptionChecker(QgsInterruptionChecker *interruptionChecker) override
Attach an object that can be queried regularly by the iterator to check if it must stopped...
QStringList referencedColumns() const
Get list of columns referenced by the expression.
QString targetFieldName
Join field in the target layer.
bool contains(const Key &key) const
GeometryType
Definition: qgis.h:111
Q_DECL_DEPRECATED QVariant evaluate(const QgsFeature *f)
Evaluate the feature and return the result.
QgsFeatureId filterFid() const
Get the feature ID that should be fetched.
QgsFeatureMap::ConstIterator mFetchAddedFeaturesIt
QgsGeometryMap::ConstIterator mFetchChangedGeomIt
const QgsRectangle & filterRect() const
Get the rectangle from which features will be taken.
Q_DECL_DEPRECATED bool prepare(const QgsFields &fields)
Get the expression ready for evaluation - find out column indexes.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeature.h:433
QgsFields fields() const
Returns the list of fields of this layer.
long srsid() const
Returns the SrsId, if available.
Supports simplification of geometries on provider side according to a distance tolerance.
int fieldNameIndex(const QString &fieldName) const
Look up field&#39;s index from name also looks up case-insensitive if there is no match otherwise...
Definition: qgsfield.cpp:534
QString & prepend(QChar ch)
void setSourceCrs(long srsid)
sets source spatial reference system (by QGIS CRS)
QgsVectorLayerFeatureIterator(QgsVectorLayerFeatureSource *source, bool ownSource, const QgsFeatureRequest &request)
QgsExpressionContext * expressionContext()
Returns the expression context used to evaluate filter expressions.
int joinFieldIndex
Join field index in the source layer.
const_iterator constBegin() const
const QgsChangedAttributesMap & changedAttributeValues()
Changed attributes values which are not commited.
bool isNull() const
test if the rectangle is null (all coordinates zero or after call to setMinimal()).
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QGis::GeometryType type() const
Returns type of the geometry as a QGis::GeometryType.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:76
const QgsAttributeList & subsetOfAttributes() const
Return the subset of attributes which at least need to be fetched.
void setAttributes(const QgsAttributes &attrs)
Sets the feature&#39;s attributes.
Definition: qgsfeature.cpp:115
bool setAttribute(int field, const QVariant &attr)
Set an attribute&#39;s value by field index.
Definition: qgsfeature.cpp:222
QMap< int, QgsExpression * > mExpressionFieldInfo
field comes from the underlying data provider of the vector layer (originIndex = index in provider&#39;s ...
Definition: qgsfield.h:194
bool setEllipsoid(const QString &ellipsoid)
Sets ellipsoid by its acronym.
bool mClosed
Set to true, as soon as the iterator is closed.
int targetFieldIndex
Join field index in the target layer.
const_iterator insert(const T &value)
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:187
QgsVectorLayer * joinLayer
resolved pointer to the joined layer
bool isClosed() const
find out whether the iterator is still valid or closed already
const QString GEO_NONE
Constant that holds the string representation for "No ellips/No CRS".
Definition: qgis.cpp:76
QgsMapLayer * mapLayer(const QString &theLayerId)
Retrieve a pointer to a loaded layer by id.
QMap< const QgsVectorJoinInfo *, FetchJoinInfo > mFetchJoinInfo
Information about joins used in the current select() statement.
void reset(T *other)
T value(int i) const
const QgsVectorJoinInfo * joinForFieldIndex(int index, const QgsFields &fields, int &sourceFieldIndex) const
Finds the vector join for a layer field index.
int joinedFieldsOffset(const QgsVectorJoinInfo *info, const QgsFields &fields)
Find out what is the first index of the join within fields.
QgsVectorLayerJoinBuffer * clone() const
Create a copy of the join buffer.
int joinField
index of field (of the joined layer) must have equal value
virtual bool simplifyGeometry(QgsGeometry *geometry) const =0
Simplifies the specified geometry.
virtual QgsAbstractFeatureSource * featureSource() const
Return feature source object that can be used for querying provider&#39;s data.
Interface that can be optionaly attached to an iterator so its nextFeature() implementaton can check ...
bool containsJoins() const
Quick way to test if there is any join at all.
QList< Key > keys() const
void updateChangedAttributes(QgsFeature &f)
Update feature with uncommited attribute updates.
QgsFeatureRequest & setFilterFid(QgsFeatureId fid)
Set feature ID that should be fetched.
Simplify using the map2pixel data to optimize the rendering of geometries.
bool exists(int i) const
Return if a field index is valid.
Definition: qgsfield.cpp:375
void setGeometry(const QgsGeometry &geom)
Set this feature&#39;s geometry from another QgsGeometry object.
Definition: qgsfeature.cpp:124
QgsVectorLayerEditBuffer * editBuffer()
Buffer with uncommitted editing operations. Only valid after editing has been turned on...
int count(const T &value) const
void iteratorClosed()
to be called by from subclass in close()
void append(const T &value)
void useAddedFeature(const QgsFeature &src, QgsFeature &f)
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context...
void resize(int size)
const_iterator constEnd() const
void setFeatureId(QgsFeatureId id)
Sets the feature ID for this feature.
Definition: qgsfeature.cpp:101
bool isNull() const
const Key & key() const
const QgsVectorJoinInfo * joinInfo
cannonical source of information about the join
QgsAttributes attributes() const
Returns the feature&#39;s attributes.
Definition: qgsfeature.cpp:110
virtual int capabilities() const
Returns a bitmask containing the supported capabilities Note, some capabilities may change depending ...
QgsFeatureRequest & disableFilter()
Disables filter conditions.
bool needsGeometry() const
Returns true if the expression uses feature geometry for some computation.
void updateFeatureGeometry(QgsFeature &f)
Update feature with uncommited geometry updates.
bool isEmpty() const
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
virtual bool prepareSimplification(const QgsSimplifyMethod &simplifyMethod) override
Setup the simplification of geometries to fetch using the specified simplify method.
bool isEmpty() const
const_iterator constEnd() const
void remove(int i)
int fieldOriginIndex(int fieldIdx) const
Get field&#39;s origin index (its meaning is specific to each type of origin)
Definition: qgsfield.cpp:419
virtual bool fetchFeature(QgsFeature &feature) override
fetch next feature, return true on success
This class wraps a request for features to a vector layer (or directly its vector data provider)...
QList< int > QgsAttributeList
const QgsFeatureIds deletedFeatureIds()
QSet< QString > CORE_EXPORT usedAttributes() const
Returns a set of used attributes.
const T & value() const
int count() const
Return number of items.
Definition: qgsfield.cpp:365
No simplification is applied.
QGis::GeometryType geometryType() const
Returns point, line or polygon.
FilterType filterType() const
Return the filter type which is currently set on this request.
QgsFeatureRequest & setFlags(const QgsFeatureRequest::Flags &flags)
Set flags that affect how features will be fetched.
iterator end()
Fetch only a subset of attributes (setSubsetOfAttributes sets this flag)
QgsExpressionFieldBuffer * mExpressionFieldBuffer
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfield.cpp:385
iterator begin()
Q_DECL_DEPRECATED 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:173
const QList< QgsField > & addedAttributes()
Added attributes fields which are not commited.
void setFields(const QgsFields &fields)
Convenience function for setting a fields for the context.
int indexFromName(const QString &name) const
Look up field&#39;s index from name. Returns -1 on error.
Definition: qgsfield.cpp:424
T * data() const
const T value(const Key &key) const
iterator find(const Key &key)
Partial snapshot of vector layer&#39;s state (only the members necessary for access to features) ...
bool contains(const T &value) const
QgsGeometry * geometry()
Get the geometry object associated with this feature.
Definition: qgsfeature.cpp:76
QgsVectorLayerFeatureSource(QgsVectorLayer *layer)
bool contains(const T &value) const
int indexOffset
at what position the joined fields start
Supports topological simplification of geometries on provider side according to a distance tolerance...
void useChangedAttributeFeature(QgsFeatureId fid, const QgsGeometry &geom, QgsFeature &f)
const QgsFeatureMap & addedFeatures()
New features which are not commited.
const Key key(const T &value) const
General purpose distance and area calculator.
void setValid(bool validity)
Sets the validity of the feature.
Definition: qgsfeature.cpp:204
QMap< QgsFeatureId, QgsFeature > QgsFeatureMap
QString & replace(int position, int n, QChar after)
QgsFeatureRequest mRequest
A copy of the feature request.
const T & at(int i) const
bool hasGeometryType() const
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
int targetField
index of field (of this layer) that drives the join
Buffers information about expression fields for a vector layer.
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call.
QHash< QString, QgsAttributes > cachedAttributes
Cache for joined attributes to provide fast lookup (size is 0 if no memory caching) ...
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:271
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Set feature IDs that should be fetched.
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request) override
Get an iterator for features matching the specified request.
QMap< QgsFeatureId, QgsAttributeMap > QgsChangedAttributesMap
Definition: qgsfeature.h:428
bool isEmpty() const
virtual bool rewind() override
reset the iterator to the starting position
static QgsProject * instance()
access to canonical QgsProject instance
Definition: qgsproject.cpp:388
virtual bool close() override
end of iterating: free the resources / lock
static QVector< int > joinSubsetIndices(QgsVectorLayer *joinLayer, const QStringList &joinFieldsSubset)
Return a vector of indices for use in join based on field names from the layer.
int count(const T &value) const
void setDistanceUnits(QGis::UnitType unit)
Sets the desired distance units for calculations involving geomCalculator(), eg "$length" and "$perim...
const QgsGeometry * constGeometry() const
Gets a const pointer to the geometry object associated with this feature.
Definition: qgsfeature.cpp:82
FieldOrigin fieldOrigin(int fieldIdx) const
Get field&#39;s origin (value from an enumeration)
Definition: qgsfield.cpp:411
OrderBy orderBy() const
Return a list of order by clauses specified for this feature request.
static QgsAbstractGeometrySimplifier * createGeometrySimplifier(const QgsSimplifyMethod &simplifyMethod)
Creates a geometry simplifier according to specified method.
Join information prepared for fast attribute id mapping in QgsVectorLayerJoinBuffer::updateFeatureAtt...
qint64 QgsFeatureId
Definition: qgsfeature.h:31
void setGeomCalculator(const QgsDistanceArea &calc)
Sets the geometry calculator used for distance and area calculations in expressions.
QList< T > toList() const
const QgsCoordinateReferenceSystem & crs() const
Returns layer&#39;s spatial reference system.
This class contains information about how to simplify geometries fetched from a QgsFeatureIterator.
iterator insert(const Key &key, const T &value)
void addJoinedAttributesCached(QgsFeature &f, const QVariant &joinValue) const
bool isEmpty() const
static QgsExpressionContextScope * projectScope()
Creates a new scope which contains variables and functions relating to the current QGIS project...
Simplify using the Douglas-Peucker algorithm ensuring that the result is a valid geometry.
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request)=0
Get an iterator for features matching the specified request.
QgsVectorDataProvider * dataProvider()
Returns the data provider.
const_iterator constEnd() const
bool nextFeature(QgsFeature &f)
const_iterator constBegin() const
This is the base class for vector data providers.
Type type() const
QgsChangedAttributesMap mChangedAttributeValues
Geometry is not required. It may still be returned if e.g. required for a filter condition.
A vector of attributes.
Definition: qgsfeature.h:115
const QList< ExpressionField > & expressions() const
Represents a vector layer which manages a vector based data sets.
const QgsAttributeList & deletedAttributeIds()
Deleted attributes fields which are not commited.
field is calculated from an expression
Definition: qgsfield.h:197
QString toString() const
QString joinLayerId
Source layer.
QgsAttributeList allAttributesList() const
Utility function to get list of attribute indexes.
Definition: qgsfield.cpp:551
void setInterruptionChecker(QgsInterruptionChecker *interruptionChecker)
Attach an object that can be queried regularly by the iterator to check if it must stopped...
MethodType methodType() const
Gets the simplification type.
void setEllipsoidalMode(bool flag)
Sets whether coordinates must be projected to ellipsoid before measuring.
void addVirtualAttributes(QgsFeature &f)
Adds attributes that don&#39;t source from the provider but are added inside QGIS Includes.
Helper template that cares of two things: 1.
const T value(const Key &key) const
QgsExpression * filterExpression() const
Returns the filter expression if set.