QGIS API Documentation  2.15.0-Master (94d88e6)
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  {
157  QgsFeatureIds changedIds;
158  QgsChangedAttributesMap::const_iterator attIt = mSource->mChangedAttributeValues.constBegin();
159  for ( ; attIt != mSource->mChangedAttributeValues.constEnd(); ++attIt )
160  {
161  changedIds << attIt.key();
162  }
164  }
165 
166  if ( request.filterType() == QgsFeatureRequest::FilterFid )
167  {
168  mFetchedFid = false;
169  }
170  else // no filter or filter by rect
171  {
172  if ( mSource->mHasEditBuffer )
173  {
175  }
176  else
177  {
179  }
180 
182  }
183 
185  {
188  }
189 }
190 
191 
193 {
194  delete mEditGeometrySimplifier;
195  mEditGeometrySimplifier = nullptr;
196 
197  qDeleteAll( mExpressionFieldInfo );
198 
199  close();
200 }
201 
202 
203 
205 {
206  f.setValid( false );
207 
208  if ( mClosed )
209  return false;
210 
212  {
213  if ( mFetchedFid )
214  return false;
215  bool res = nextFeatureFid( f );
216  mFetchedFid = true;
217  return res;
218  }
219 
220  if ( !mRequest.filterRect().isNull() )
221  {
222  if ( fetchNextChangedGeomFeature( f ) )
223  return true;
224 
225  // no more changed geometries
226  }
227 
229  {
231  return true;
232 
233  // no more changed features
234  }
235 
236  while ( fetchNextAddedFeature( f ) )
237  {
238  return true;
239  }
240  // no more added features
241 
242  if ( mProviderIterator.isClosed() )
243  {
246  mProviderIterator.setInterruptionChecker( mInterruptionChecker );
247  }
248 
249  while ( mProviderIterator.nextFeature( f ) )
250  {
251  if ( mFetchConsidered.contains( f.id() ) )
252  continue;
253 
254  // TODO[MD]: just one resize of attributes
255  f.setFields( mSource->mFields );
256 
257  // update attributes
258  if ( mSource->mHasEditBuffer )
260 
261  if ( mHasVirtualAttributes )
263 
265  {
266  //filtering by expression, and couldn't do it on the provider side
269  {
270  //feature did not match filter
271  continue;
272  }
273  }
274 
275  // update geometry
276  // TODO[MK]: FilterRect check after updating the geometry
279 
280  return true;
281  }
282  // no more provider features
283 
284  close();
285  return false;
286 }
287 
288 
289 
291 {
292  if ( mClosed )
293  return false;
294 
296  {
297  mFetchedFid = false;
298  }
299  else
300  {
303  }
304 
305  return true;
306 }
307 
309 {
310  if ( mClosed )
311  return false;
312 
314 
315  iteratorClosed();
316 
317  mClosed = true;
318  return true;
319 }
320 
322 {
323  mProviderIterator.setInterruptionChecker( interruptionChecker );
324  mInterruptionChecker = interruptionChecker;
325 }
326 
328 {
330  {
332 
333  if ( mFetchConsidered.contains( fid ) )
334  // must have changed geometry outside rectangle
335  continue;
336 
338  // skip features which are not accepted by the filter
339  continue;
340 
342 
343  return true;
344  }
345 
347  return false; // no more added features
348 }
349 
350 
352 {
353  f.setFeatureId( src.id() );
354  f.setValid( true );
355  f.setFields( mSource->mFields );
356 
358  {
359  f.setGeometry( new QgsGeometry( *src.constGeometry() ) );
360 
361  // simplify the edited geometry using its simplifier configured
362  if ( mEditGeometrySimplifier )
363  {
364  QgsGeometry* geometry = f.geometry();
365  QGis::GeometryType geometryType = geometry->type();
366  if ( geometryType == QGis::Line || geometryType == QGis::Polygon ) mEditGeometrySimplifier->simplifyGeometry( geometry );
367  }
368  }
369 
370  // TODO[MD]: if subset set just some attributes
371 
372  f.setAttributes( src.attributes() );
373 
374  if ( mHasVirtualAttributes )
376 }
377 
378 
379 
381 {
382  // check if changed geometries are in rectangle
384  {
385  QgsFeatureId fid = mFetchChangedGeomIt.key();
386 
387  if ( mFetchConsidered.contains( fid ) )
388  // skip deleted features
389  continue;
390 
391  mFetchConsidered << fid;
392 
393  if ( !mFetchChangedGeomIt->intersects( mRequest.filterRect() ) )
394  // skip changed geometries not in rectangle and don't check again
395  continue;
396 
398 
399  // return complete feature
401  return true;
402  }
403 
404  return false; // no more changed geometries
405 }
406 
408 {
410  {
411  if ( mFetchConsidered.contains( f.id() ) )
412  // skip deleted features and those already handled by the geometry
413  continue;
414 
415  mFetchConsidered << f.id();
416 
418 
419  if ( mHasVirtualAttributes )
421 
424  {
425  return true;
426  }
427  }
428 
429  return false;
430 }
431 
432 
434 {
435  f.setFeatureId( fid );
436  f.setValid( true );
437  f.setFields( mSource->mFields );
438 
440  {
441  f.setGeometry( geom );
442 
443  // simplify the edited geometry using its simplifier configured
444  if ( mEditGeometrySimplifier )
445  {
446  QgsGeometry* geometry = f.geometry();
447  QGis::GeometryType geometryType = geometry->type();
448  if ( geometryType == QGis::Line || geometryType == QGis::Polygon ) mEditGeometrySimplifier->simplifyGeometry( geometry );
449  }
450  }
451 
452  bool subsetAttrs = ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes );
453  if ( !subsetAttrs || !mRequest.subsetOfAttributes().isEmpty() )
454  {
455  // retrieve attributes from provider
456  QgsFeature tmp;
457  //mDataProvider->featureAtId( fid, tmp, false, mFetchProvAttributes );
458  QgsFeatureRequest request;
460  if ( subsetAttrs )
461  {
463  }
465  if ( fi.nextFeature( tmp ) )
466  {
469  f.setAttributes( tmp.attributes() );
470  }
471  }
472 
474 }
475 
476 
477 
479 {
481 
484 }
485 
486 
487 
489 {
491  QgsAttributeList sourceJoinFields; // attributes that also need to be fetched from this layer in order to have joins working
492 
493  mFetchJoinInfo.clear();
494 
495  for ( QgsAttributeList::const_iterator attIt = fetchAttributes.constBegin(); attIt != fetchAttributes.constEnd(); ++attIt )
496  {
497  if ( !mSource->mFields.exists( *attIt ) )
498  continue;
499 
500  if ( mSource->mFields.fieldOrigin( *attIt ) != QgsFields::OriginJoin )
501  continue;
502 
503  int sourceLayerIndex;
504  const QgsVectorJoinInfo* joinInfo = mSource->mJoinBuffer->joinForFieldIndex( *attIt, mSource->mFields, sourceLayerIndex );
505  Q_ASSERT( joinInfo );
506 
507  QgsVectorLayer* joinLayer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( joinInfo->joinLayerId ) );
508  Q_ASSERT( joinLayer );
509 
510  if ( !mFetchJoinInfo.contains( joinInfo ) )
511  {
512  FetchJoinInfo info;
513  info.joinInfo = joinInfo;
514  info.joinLayer = joinLayer;
516 
517  if ( joinInfo->targetFieldName.isEmpty() )
518  info.targetField = joinInfo->targetFieldIndex; //for compatibility with 1.x
519  else
521 
522  if ( joinInfo->joinFieldName.isEmpty() )
523  info.joinField = joinInfo->joinFieldIndex; //for compatibility with 1.x
524  else
525  info.joinField = joinLayer->fields().indexFromName( joinInfo->joinFieldName );
526 
527  // for joined fields, we always need to request the targetField from the provider too
528  if ( !fetchAttributes.contains( info.targetField ) )
529  sourceJoinFields << info.targetField;
530 
531  mFetchJoinInfo.insert( joinInfo, info );
532  }
533 
534  // store field source index - we'll need it when fetching from provider
535  mFetchJoinInfo[ joinInfo ].attributes.push_back( sourceLayerIndex );
536  }
537 
538  // add sourceJoinFields if we're using a subset
541 }
542 
544 {
546 
547  mExpressionContext.reset( new QgsExpressionContext() );
548  mExpressionContext->appendScope( QgsExpressionContextUtils::globalScope() );
549  mExpressionContext->appendScope( QgsExpressionContextUtils::projectScope() );
550  mExpressionContext->setFields( mSource->mFields );
551 
552  for ( int i = 0; i < mSource->mFields.count(); i++ )
553  {
555  {
556  // Only prepare if there is no subset defined or the subset contains this field
559  {
560  int oi = mSource->mFields.fieldOriginIndex( i );
561  QgsExpression* exp = new QgsExpression( exps[oi].cachedExpression );
562 
563  QgsDistanceArea da;
564  da.setSourceCrs( mSource->mCrsId );
565  da.setEllipsoidalMode( true );
566  da.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
567  exp->setGeomCalculator( da );
568  exp->setDistanceUnits( QgsProject::instance()->distanceUnits() );
569  exp->setAreaUnits( QgsProject::instance()->areaUnits() );
570 
571  exp->prepare( mExpressionContext.data() );
572  mExpressionFieldInfo.insert( i, exp );
573 
575  {
576  QgsAttributeList attrs;
577  Q_FOREACH ( const QString& col, exp->referencedColumns() )
578  {
579  attrs.append( mSource->mFields.fieldNameIndex( col ) );
580  }
581 
583  }
584 
585  if ( exp->needsGeometry() )
586  {
587  mRequest.setFlags( mRequest.flags() & ~QgsFeatureRequest::NoGeometry );
588  }
589  }
590  }
591  }
592 }
593 
595 {
597  for ( ; joinIt != mFetchJoinInfo.constEnd(); ++joinIt )
598  {
599  const FetchJoinInfo& info = joinIt.value();
600  Q_ASSERT( joinIt.key() );
601 
602  QVariant targetFieldValue = f.attribute( info.targetField );
603  if ( !targetFieldValue.isValid() )
604  continue;
605 
606  const QHash< QString, QgsAttributes>& memoryCache = info.joinInfo->cachedAttributes;
607  if ( memoryCache.isEmpty() )
608  info.addJoinedAttributesDirect( f, targetFieldValue );
609  else
610  info.addJoinedAttributesCached( f, targetFieldValue );
611  }
612 }
613 
615 {
616  // make sure we have space for newly added attributes
617  QgsAttributes attr = f.attributes();
618  attr.resize( mSource->mFields.count() ); // Provider attrs count + joined attrs count + expression attrs count
619  f.setAttributes( attr );
620 
621  if ( !mFetchJoinInfo.isEmpty() )
622  addJoinedAttributes( f );
623 
624  if ( !mExpressionFieldInfo.isEmpty() )
625  {
627 
628  for ( ; it != mExpressionFieldInfo.constEnd(); ++it )
629  {
630  QgsExpression* exp = it.value();
631  mExpressionContext->setFeature( f );
632  QVariant val = exp->evaluate( mExpressionContext.data() );
633  mSource->mFields.at( it.key() ).convertCompatible( val );
634  f.setAttribute( it.key(), val );
635  }
636  }
637 }
638 
640 {
641  delete mEditGeometrySimplifier;
642  mEditGeometrySimplifier = nullptr;
643 
644  // setup simplification for edited geometries to fetch
646  {
647  mEditGeometrySimplifier = QgsSimplifyMethod::createGeometrySimplifier( simplifyMethod );
648  return nullptr != mEditGeometrySimplifier;
649  }
650  return false;
651 }
652 
653 bool QgsVectorLayerFeatureIterator::providerCanSimplify( QgsSimplifyMethod::MethodType methodType ) const
654 {
655  Q_UNUSED( methodType );
656 #if 0
657  // TODO[MD]: after merge
658  QgsVectorDataProvider* provider = L->dataProvider();
659 
660  if ( provider && methodType != QgsSimplifyMethod::NoSimplification )
661  {
662  int capabilities = provider->capabilities();
663 
664  if ( methodType == QgsSimplifyMethod::OptimizeForRendering )
665  {
666  return ( capabilities & QgsVectorDataProvider::SimplifyGeometries );
667  }
668  else if ( methodType == QgsSimplifyMethod::PreserveTopology )
669  {
671  }
672  }
673 #endif
674  return false;
675 }
676 
677 
679 {
680  const QHash<QString, QgsAttributes>& memoryCache = joinInfo->cachedAttributes;
681  QHash<QString, QgsAttributes>::const_iterator it = memoryCache.find( joinValue.toString() );
682  if ( it == memoryCache.constEnd() )
683  return; // joined value not found -> leaving the attributes empty (null)
684 
685  int index = indexOffset;
686 
687  const QgsAttributes& featureAttributes = it.value();
688  for ( int i = 0; i < featureAttributes.count(); ++i )
689  {
690  f.setAttribute( index++, featureAttributes.at( i ) );
691  }
692 }
693 
694 
695 
697 {
698  // no memory cache, query the joined values by setting substring
699  QString subsetString;
700 
701  QString joinFieldName;
702  if ( joinInfo->joinFieldName.isEmpty() && joinInfo->joinFieldIndex >= 0 && joinInfo->joinFieldIndex < joinLayer->fields().count() )
703  joinFieldName = joinLayer->fields().field( joinInfo->joinFieldIndex ).name(); // for compatibility with 1.x
704  else
705  joinFieldName = joinInfo->joinFieldName;
706 
707  subsetString.append( QString( "\"%1\"" ).arg( joinFieldName ) );
708 
709  if ( joinValue.isNull() )
710  {
711  subsetString += " IS NULL";
712  }
713  else
714  {
715  QString v = joinValue.toString();
716  switch ( joinValue.type() )
717  {
718  case QVariant::Int:
719  case QVariant::LongLong:
720  case QVariant::Double:
721  break;
722 
723  default:
724  case QVariant::String:
725  v.replace( '\'', "''" );
726  v.prepend( '\'' ).append( '\'' );
727  break;
728  }
729  subsetString += '=' + v;
730  }
731 
732  // maybe user requested just a subset of layer's attributes
733  // so we do not have to cache everything
734  bool hasSubset = joinInfo->joinFieldNamesSubset();
735  QVector<int> subsetIndices;
736  if ( hasSubset )
737  subsetIndices = QgsVectorLayerJoinBuffer::joinSubsetIndices( joinLayer, *joinInfo->joinFieldNamesSubset() );
738 
739  // select (no geometry)
740  QgsFeatureRequest request;
742  request.setSubsetOfAttributes( attributes );
743  request.setFilterExpression( subsetString );
744  request.setLimit( 1 );
745  QgsFeatureIterator fi = joinLayer->getFeatures( request );
746 
747  // get first feature
748  QgsFeature fet;
749  if ( fi.nextFeature( fet ) )
750  {
751  int index = indexOffset;
752  QgsAttributes attr = fet.attributes();
753  if ( hasSubset )
754  {
755  for ( int i = 0; i < subsetIndices.count(); ++i )
756  f.setAttribute( index++, attr.at( subsetIndices.at( i ) ) );
757  }
758  else
759  {
760  // use all fields except for the one used for join (has same value as exiting field in target layer)
761  for ( int i = 0; i < attr.count(); ++i )
762  {
763  if ( i == joinField )
764  continue;
765 
766  f.setAttribute( index++, attr.at( i ) );
767  }
768  }
769  }
770  else
771  {
772  // no suitable join feature found, keeping empty (null) attributes
773  }
774 }
775 
776 
777 
778 
780 {
781  QgsFeatureId featureId = mRequest.filterFid();
782 
783  // deleted already?
784  if ( mSource->mDeletedFeatureIds.contains( featureId ) )
785  return false;
786 
787  // has changed geometry?
789  {
790  useChangedAttributeFeature( featureId, mSource->mChangedGeometries[featureId], f );
791  return true;
792  }
793 
794  // added features
796  {
797  if ( iter->id() == featureId )
798  {
799  useAddedFeature( *iter, f );
800  return true;
801  }
802  }
803 
804  // regular features
806  if ( fi.nextFeature( f ) )
807  {
808  f.setFields( mSource->mFields );
809 
810  if ( mSource->mHasEditBuffer )
812 
813  if ( mHasVirtualAttributes )
815 
816  return true;
817  }
818 
819  return false;
820 }
821 
823 {
824  QgsAttributes attrs = f.attributes();
825 
826  // remove all attributes that will disappear - from higher indices to lower
827  for ( int idx = mSource->mDeletedAttributeIds.count() - 1; idx >= 0; --idx )
828  {
829  attrs.remove( mSource->mDeletedAttributeIds[idx] );
830  }
831 
832  // adjust size to accommodate added attributes
833  attrs.resize( attrs.count() + mSource->mAddedAttributes.count() );
834 
835  // update changed attributes
837  {
839  for ( QgsAttributeMap::const_iterator it = map.begin(); it != map.end(); ++it )
840  attrs[it.key()] = it.value();
841  }
842  f.setAttributes( attrs );
843 }
844 
846 {
847  if ( mSource->mChangedGeometries.contains( f.id() ) )
849 }
850 
851 bool QgsVectorLayerFeatureIterator::prepareOrderBy( const QList<QgsFeatureRequest::OrderByClause>& orderBys )
852 {
853  Q_UNUSED( orderBys );
854  return true;
855 }
856 
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:437
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:201
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:115
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:439
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:200
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.
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...
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
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:434
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
QgsFeatureRequest & setLimit(long limit)
Set the maximum number of features to request.
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:203
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.