QGIS API Documentation  2.9.0-Master
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 
27 {
29  mFields = layer->pendingFields();
30  mJoinBuffer = layer->mJoinBuffer->clone();
31  mExpressionFieldBuffer = new QgsExpressionFieldBuffer( *layer->mExpressionFieldBuffer );
32 
33  mCanBeSimplified = layer->hasGeometryType() && layer->geometryType() != QGis::Point;
34 
35  mHasEditBuffer = layer->editBuffer();
36  if ( mHasEditBuffer )
37  {
38 #if 0
39  // TODO[MD]: after merge
40  if ( request.filterType() == QgsFeatureRequest::FilterFid )
41  {
42 
43  // only copy relevant parts
44  if ( L->editBuffer()->addedFeatures().contains( request.filterFid() ) )
45  mAddedFeatures.insert( request.filterFid(), L->editBuffer()->addedFeatures()[ request.filterFid()] );
46 
47  if ( L->editBuffer()->changedGeometries().contains( request.filterFid() ) )
48  mChangedGeometries.insert( request.filterFid(), L->editBuffer()->changedGeometries()[ request.filterFid()] );
49 
50  if ( L->editBuffer()->deletedFeatureIds().contains( request.filterFid() ) )
51  mDeletedFeatureIds.insert( request.filterFid() );
52 
53  if ( L->editBuffer()->changedAttributeValues().contains( request.filterFid() ) )
54  mChangedAttributeValues.insert( request.filterFid(), L->editBuffer()->changedAttributeValues()[ request.filterFid()] );
55 
56  if ( L->editBuffer()->changedAttributeValues().contains( request.filterFid() ) )
57  mChangedFeaturesRequest.setFilterFids( QgsFeatureIds() << request.filterFid() );
58  }
59  else
60  {
61 #endif
66  mAddedAttributes = QList<QgsField>( layer->editBuffer()->addedAttributes() );
68 #if 0
69  }
70 #endif
71  }
72 }
73 
75 {
76  delete mJoinBuffer;
79 }
80 
82 {
83  // return feature iterator that does not own this source
84  return QgsFeatureIterator( new QgsVectorLayerFeatureIterator( this, false, request ) );
85 }
86 
87 
90  , mFetchedFid( false )
91  , mEditGeometrySimplifier( 0 )
92 {
93 
94  // prepare joins: may add more attributes to fetch (in order to allow join)
96  prepareJoins();
97 
99 
100  mHasVirtualAttributes = !mFetchJoinInfo.isEmpty() || !mExpressionFieldInfo.isEmpty();
101 
102  // by default provider's request is the same
104 
106  {
107  // prepare list of attributes to match provider fields
108  QgsAttributeList providerSubset;
110  int nPendingFields = mSource->mFields.count();
111  for ( int i = 0; i < subset.count(); ++i )
112  {
113  int attrIndex = subset[i];
114  if ( attrIndex < 0 || attrIndex >= nPendingFields ) continue;
115  if ( mSource->mFields.fieldOrigin( attrIndex ) == QgsFields::OriginProvider )
116  providerSubset << mSource->mFields.fieldOriginIndex( attrIndex );
117  }
118  mProviderRequest.setSubsetOfAttributes( providerSubset );
119  }
120 
121  if ( mSource->mHasEditBuffer )
122  {
125  }
126 
127  if ( request.filterType() == QgsFeatureRequest::FilterFid )
128  {
129  mFetchedFid = false;
130  }
131  else // no filter or filter by rect
132  {
133  if ( mSource->mHasEditBuffer )
134  {
136  }
137  else
138  {
140  }
141 
143  }
144 
146  {
148  }
149 }
150 
151 
153 {
154  delete mEditGeometrySimplifier;
155  mEditGeometrySimplifier = NULL;
156 
157  qDeleteAll( mExpressionFieldInfo.values() );
158 
159  close();
160 }
161 
162 
163 
165 {
166  f.setValid( false );
167 
168  if ( mClosed )
169  return false;
170 
172  {
173  if ( mFetchedFid )
174  return false;
175  bool res = nextFeatureFid( f );
176  mFetchedFid = true;
177  return res;
178  }
179 
181  {
182  if ( fetchNextChangedGeomFeature( f ) )
183  return true;
184 
185  // no more changed geometries
186  }
187 
189  {
191  return true;
192 
193  // no more changed features
194  }
195 
196  while ( fetchNextAddedFeature( f ) )
197  {
198  return true;
199  }
200  // no more added features
201 
202  if ( mProviderIterator.isClosed() )
203  {
206  }
207 
208  while ( mProviderIterator.nextFeature( f ) )
209  {
210  if ( mFetchConsidered.contains( f.id() ) )
211  continue;
212 
213  // TODO[MD]: just one resize of attributes
214  f.setFields( mSource->mFields );
215 
216  // update attributes
217  if ( mSource->mHasEditBuffer )
219 
220  if ( mHasVirtualAttributes )
222 
223  // update geometry
224  // TODO[MK]: FilterRect check after updating the geometry
227 
228  return true;
229  }
230  // no more provider features
231 
232  close();
233  return false;
234 }
235 
236 
237 
239 {
240  if ( mClosed )
241  return false;
242 
244  {
245  mFetchedFid = false;
246  }
247  else
248  {
251  }
252 
253  return true;
254 }
255 
257 {
258  if ( mClosed )
259  return false;
260 
262 
263  iteratorClosed();
264 
265  mClosed = true;
266  return true;
267 }
268 
269 
270 
271 
273 {
274  while ( mFetchAddedFeaturesIt-- != mSource->mAddedFeatures.constBegin() )
275  {
277 
278  if ( mFetchConsidered.contains( fid ) )
279  // must have changed geometry outside rectangle
280  continue;
281 
283  // skip features which are not accepted by the filter
284  continue;
285 
287 
288  return true;
289  }
290 
292  return false; // no more added features
293 }
294 
295 
297 {
298  f.setFeatureId( src.id() );
299  f.setValid( true );
300  f.setFields( mSource->mFields );
301 
303  {
304  f.setGeometry( new QgsGeometry( *src.constGeometry() ) );
305 
306  // simplify the edited geometry using its simplifier configured
307  if ( mEditGeometrySimplifier )
308  {
309  QgsGeometry* geometry = f.geometry();
310  QGis::GeometryType geometryType = geometry->type();
311  if ( geometryType == QGis::Line || geometryType == QGis::Polygon ) mEditGeometrySimplifier->simplifyGeometry( geometry );
312  }
313  }
314 
315  // TODO[MD]: if subset set just some attributes
316 
317  f.setAttributes( src.attributes() );
318 
319  if ( mHasVirtualAttributes )
321 }
322 
323 
324 
326 {
327  // check if changed geometries are in rectangle
329  {
330  QgsFeatureId fid = mFetchChangedGeomIt.key();
331 
332  if ( mFetchConsidered.contains( fid ) )
333  // skip deleted features
334  continue;
335 
336  mFetchConsidered << fid;
337 
338  if ( !mFetchChangedGeomIt->intersects( mRequest.filterRect() ) )
339  // skip changed geometries not in rectangle and don't check again
340  continue;
341 
343 
344  // return complete feature
346  return true;
347  }
348 
349  return false; // no more changed geometries
350 }
351 
353 {
355  {
356  mFetchConsidered << f.id();
357 
359 
360  if ( mHasVirtualAttributes )
362 
364  {
365  if ( mRequest.filterExpression()->evaluate( &f ).toBool() )
366  {
367  return true;
368  }
369  }
370  else
371  {
372  return true;
373  }
374  }
375 
376  return false;
377 }
378 
379 
381 {
382  f.setFeatureId( fid );
383  f.setValid( true );
384  f.setFields( mSource->mFields );
385 
387  {
388  f.setGeometry( geom );
389 
390  // simplify the edited geometry using its simplifier configured
391  if ( mEditGeometrySimplifier )
392  {
393  QgsGeometry* geometry = f.geometry();
394  QGis::GeometryType geometryType = geometry->type();
395  if ( geometryType == QGis::Line || geometryType == QGis::Polygon ) mEditGeometrySimplifier->simplifyGeometry( geometry );
396  }
397  }
398 
399  bool subsetAttrs = ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes );
400  if ( !subsetAttrs || ( subsetAttrs && mRequest.subsetOfAttributes().count() > 0 ) )
401  {
402  // retrieve attributes from provider
403  QgsFeature tmp;
404  //mDataProvider->featureAtId( fid, tmp, false, mFetchProvAttributes );
405  QgsFeatureRequest request;
407  if ( subsetAttrs )
408  {
410  }
412  if ( fi.nextFeature( tmp ) )
413  {
416  f.setAttributes( tmp.attributes() );
417  }
418  }
419 
421 }
422 
423 
424 
426 {
428 
431 }
432 
433 
434 
436 {
438  QgsAttributeList sourceJoinFields; // attributes that also need to be fetched from this layer in order to have joins working
439 
440  mFetchJoinInfo.clear();
441 
442  for ( QgsAttributeList::const_iterator attIt = fetchAttributes.constBegin(); attIt != fetchAttributes.constEnd(); ++attIt )
443  {
444  if ( !mSource->mFields.exists( *attIt ) )
445  continue;
446 
447  if ( mSource->mFields.fieldOrigin( *attIt ) != QgsFields::OriginJoin )
448  continue;
449 
450  int sourceLayerIndex;
451  const QgsVectorJoinInfo* joinInfo = mSource->mJoinBuffer->joinForFieldIndex( *attIt, mSource->mFields, sourceLayerIndex );
452  Q_ASSERT( joinInfo );
453 
454  QgsVectorLayer* joinLayer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( joinInfo->joinLayerId ) );
455  Q_ASSERT( joinLayer );
456 
457  if ( !mFetchJoinInfo.contains( joinInfo ) )
458  {
459  FetchJoinInfo info;
460  info.joinInfo = joinInfo;
461  info.joinLayer = joinLayer;
463 
464  if ( joinInfo->targetFieldName.isEmpty() )
465  info.targetField = joinInfo->targetFieldIndex; //for compatibility with 1.x
466  else
468 
469  if ( joinInfo->joinFieldName.isEmpty() )
470  info.joinField = joinInfo->joinFieldIndex; //for compatibility with 1.x
471  else
472  info.joinField = joinLayer->pendingFields().indexFromName( joinInfo->joinFieldName );
473 
474  // for joined fields, we always need to request the targetField from the provider too
475  if ( !fetchAttributes.contains( info.targetField ) )
476  sourceJoinFields << info.targetField;
477 
478  mFetchJoinInfo.insert( joinInfo, info );
479  }
480 
481  // store field source index - we'll need it when fetching from provider
482  mFetchJoinInfo[ joinInfo ].attributes.push_back( sourceLayerIndex );
483  }
484 
485  // add sourceJoinFields if we're using a subset
488 }
489 
491 {
492  const QList<QgsExpressionFieldBuffer::ExpressionField> exps = mSource->mExpressionFieldBuffer->expressions();
493 
494  for ( int i = 0; i < mSource->mFields.count(); i++ )
495  {
497  {
498  // Only prepare if there is no subset defined or the subset contains this field
500  || mRequest.subsetOfAttributes().contains( i ) )
501  {
502  int oi = mSource->mFields.fieldOriginIndex( i );
503  QgsExpression* exp = new QgsExpression( exps[oi].expression );
504  exp->prepare( mSource->mFields );
505  mExpressionFieldInfo.insert( i, exp );
506 
508  {
509  QgsAttributeList attrs;
510  Q_FOREACH ( const QString& col, exp->referencedColumns() )
511  {
512  attrs.append( mSource->mFields.fieldNameIndex( col ) );
513  }
514 
516  }
517 
518  if ( exp->needsGeometry() )
519  {
520  mRequest.setFlags( mRequest.flags() & ~QgsFeatureRequest::NoGeometry );
521  }
522  }
523  }
524  }
525 }
526 
528 {
529  QMap<const QgsVectorJoinInfo*, FetchJoinInfo>::const_iterator joinIt = mFetchJoinInfo.constBegin();
530  for ( ; joinIt != mFetchJoinInfo.constEnd(); ++joinIt )
531  {
532  const FetchJoinInfo& info = joinIt.value();
533  Q_ASSERT( joinIt.key() );
534 
535  QVariant targetFieldValue = f.attribute( info.targetField );
536  if ( !targetFieldValue.isValid() )
537  continue;
538 
539  const QHash< QString, QgsAttributes>& memoryCache = info.joinInfo->cachedAttributes;
540  if ( memoryCache.isEmpty() )
541  info.addJoinedAttributesDirect( f, targetFieldValue );
542  else
543  info.addJoinedAttributesCached( f, targetFieldValue );
544  }
545 }
546 
548 {
549  // make sure we have space for newly added attributes
550  QgsAttributes attr = f.attributes();
551  attr.resize( mSource->mFields.count() ); // Provider attrs count + joined attrs count + expression attrs count
552  f.setAttributes( attr );
553 
554  if ( !mFetchJoinInfo.isEmpty() )
555  addJoinedAttributes( f );
556 
557  if ( !mExpressionFieldInfo.isEmpty() )
558  {
559  QMap<int, QgsExpression*>::ConstIterator it = mExpressionFieldInfo.constBegin();
560 
561  for ( ; it != mExpressionFieldInfo.constEnd(); ++it )
562  {
563  QgsExpression* exp = it.value();
564  QVariant val = exp->evaluate( f );
565  mSource->mFields.at( it.key() ).convertCompatible( val );;
566  f.setAttribute( it.key(), val );
567  }
568  }
569 }
570 
572 {
573  delete mEditGeometrySimplifier;
574  mEditGeometrySimplifier = NULL;
575 
576  // setup simplification for edited geometries to fetch
578  {
579  mEditGeometrySimplifier = QgsSimplifyMethod::createGeometrySimplifier( simplifyMethod );
580  return mEditGeometrySimplifier != NULL;
581  }
582  return false;
583 }
584 
585 bool QgsVectorLayerFeatureIterator::providerCanSimplify( QgsSimplifyMethod::MethodType methodType ) const
586 {
587  Q_UNUSED( methodType );
588 #if 0
589  // TODO[MD]: after merge
590  QgsVectorDataProvider* provider = L->dataProvider();
591 
592  if ( provider && methodType != QgsSimplifyMethod::NoSimplification )
593  {
594  int capabilities = provider->capabilities();
595 
596  if ( methodType == QgsSimplifyMethod::OptimizeForRendering )
597  {
598  return ( capabilities & QgsVectorDataProvider::SimplifyGeometries );
599  }
600  else if ( methodType == QgsSimplifyMethod::PreserveTopology )
601  {
603  }
604  }
605 #endif
606  return false;
607 }
608 
609 
611 {
612  const QHash<QString, QgsAttributes>& memoryCache = joinInfo->cachedAttributes;
613  QHash<QString, QgsAttributes>::const_iterator it = memoryCache.find( joinValue.toString() );
614  if ( it == memoryCache.constEnd() )
615  return; // joined value not found -> leaving the attributes empty (null)
616 
617  int index = indexOffset;
618 
619  const QgsAttributes& featureAttributes = it.value();
620  for ( int i = 0; i < featureAttributes.count(); ++i )
621  {
622  f.setAttribute( index++, featureAttributes[i] );
623  }
624 }
625 
626 
627 
629 {
630  // no memory cache, query the joined values by setting substring
631  QString subsetString = joinLayer->dataProvider()->subsetString(); // provider might already have a subset string
632  QString bkSubsetString = subsetString;
633  if ( !subsetString.isEmpty() )
634  {
635  subsetString.prepend( "(" ).append( ") AND " );
636  }
637 
638  QString joinFieldName;
639  if ( joinInfo->joinFieldName.isEmpty() && joinInfo->joinFieldIndex >= 0 && joinInfo->joinFieldIndex < joinLayer->pendingFields().count() )
640  joinFieldName = joinLayer->pendingFields().field( joinInfo->joinFieldIndex ).name(); // for compatibility with 1.x
641  else
642  joinFieldName = joinInfo->joinFieldName;
643 
644  subsetString.append( QString( "\"%1\"" ).arg( joinFieldName ) );
645 
646  if ( joinValue.isNull() )
647  {
648  subsetString += " IS NULL";
649  }
650  else
651  {
652  QString v = joinValue.toString();
653  switch ( joinValue.type() )
654  {
655  case QVariant::Int:
656  case QVariant::LongLong:
657  case QVariant::Double:
658  break;
659 
660  default:
661  case QVariant::String:
662  v.replace( "'", "''" );
663  v.prepend( "'" ).append( "'" );
664  break;
665  }
666  subsetString += "=" + v;
667  }
668 
669  joinLayer->dataProvider()->setSubsetString( subsetString, false );
670 
671  // maybe user requested just a subset of layer's attributes
672  // so we do not have to cache everything
673  bool hasSubset = joinInfo->joinFieldNamesSubset();
674  QVector<int> subsetIndices;
675  if ( hasSubset )
676  subsetIndices = QgsVectorLayerJoinBuffer::joinSubsetIndices( joinLayer, *joinInfo->joinFieldNamesSubset() );
677 
678  // select (no geometry)
679  QgsFeatureRequest request;
681  request.setSubsetOfAttributes( attributes );
682  QgsFeatureIterator fi = joinLayer->getFeatures( request );
683 
684  // get first feature
685  QgsFeature fet;
686  if ( fi.nextFeature( fet ) )
687  {
688  int index = indexOffset;
689  QgsAttributes attr = fet.attributes();
690  if ( hasSubset )
691  {
692  for ( int i = 0; i < subsetIndices.count(); ++i )
693  f.setAttribute( index++, attr[ subsetIndices[i] ] );
694  }
695  else
696  {
697  // use all fields except for the one used for join (has same value as exiting field in target layer)
698  for ( int i = 0; i < attr.count(); ++i )
699  {
700  if ( i == joinField )
701  continue;
702 
703  f.setAttribute( index++, attr[i] );
704  }
705  }
706  }
707  else
708  {
709  // no suitable join feature found, keeping empty (null) attributes
710  }
711 
712  joinLayer->dataProvider()->setSubsetString( bkSubsetString, false );
713 }
714 
715 
716 
717 
719 {
720  QgsFeatureId featureId = mRequest.filterFid();
721 
722  // deleted already?
723  if ( mSource->mDeletedFeatureIds.contains( featureId ) )
724  return false;
725 
726  // has changed geometry?
727  if ( !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) && mSource->mChangedGeometries.contains( featureId ) )
728  {
729  useChangedAttributeFeature( featureId, mSource->mChangedGeometries[featureId], f );
730  return true;
731  }
732 
733  // added features
734  for ( QgsFeatureMap::ConstIterator iter = mSource->mAddedFeatures.constBegin(); iter != mSource->mAddedFeatures.constEnd(); ++iter )
735  {
736  if ( iter->id() == featureId )
737  {
738  useAddedFeature( *iter, f );
739  return true;
740  }
741  }
742 
743  // regular features
745  if ( fi.nextFeature( f ) )
746  {
747  if ( mSource->mHasEditBuffer )
749 
750  if ( mHasVirtualAttributes )
752 
753  return true;
754  }
755 
756  return false;
757 }
758 
760 {
761  QgsAttributes attrs = f.attributes();
762 
763  // remove all attributes that will disappear - from higher indices to lower
764  for ( int idx = mSource->mDeletedAttributeIds.count() - 1; idx >= 0; --idx )
765  {
766  attrs.remove( mSource->mDeletedAttributeIds[idx] );
767  }
768 
769  // adjust size to accommodate added attributes
770  attrs.resize( attrs.count() + mSource->mAddedAttributes.count() );
771 
772  // update changed attributes
773  if ( mSource->mChangedAttributeValues.contains( f.id() ) )
774  {
776  for ( QgsAttributeMap::const_iterator it = map.begin(); it != map.end(); ++it )
777  attrs[it.key()] = it.value();
778  }
779  f.setAttributes( attrs );
780 }
781 
783 {
784  if ( mSource->mChangedGeometries.contains( f.id() ) )
786 }
787 
QgsFeatureId id() const
Get the feature ID for this feature.
Definition: qgsfeature.cpp:51
const QgsGeometryMap & changedGeometries()
Changed geometries which are not commited.
QgsAbstractFeatureSource * mProviderFeatureSource
Class for parsing and evaluation of expressions (formerly called "search strings").
Definition: qgsexpression.h:86
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:363
supports topological simplification of geometries on provider side according to a distance tolerance ...
static unsigned index
bool acceptFeature(const QgsFeature &feature)
Check if a feature is accepted by this requests filter.
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:181
QStringList referencedColumns() const
Get list of columns referenced by the expression.
QString targetFieldName
Join field in the target layer.
QMap< int, QVariant > QgsAttributeMap
Definition: qgsfeature.h:104
QgsFeatureMap::ConstIterator mFetchAddedFeaturesIt
QgsGeometryMap::ConstIterator mFetchChangedGeomIt
QVariant evaluate(const QgsFeature *f=NULL)
Evaluate the feature and return the result.
const QgsRectangle & filterRect() const
bool prepare(const QgsFields &fields)
Get the expression ready for evaluation - find out column indexes.
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeature.h:365
int fieldNameIndex(const QString &fieldName) const
Look up field's index from name - case insensitive TODO: sort out case sensitive (indexFromName()) vs...
Definition: qgsfield.cpp:354
QgsVectorLayerFeatureIterator(QgsVectorLayerFeatureSource *source, bool ownSource, const QgsFeatureRequest &request)
int joinFieldIndex
Join field index in the source layer.
const QgsChangedAttributesMap & changedAttributeValues()
Changed attributes values which are not commited.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
const QgsAttributeList & subsetOfAttributes() const
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
Definition: qgsfeature.cpp:95
bool setAttribute(int field, const QVariant &attr)
Set an attribute's value by field index.
Definition: qgsfeature.cpp:192
QMap< int, QgsExpression * > mExpressionFieldInfo
GeometryType
Definition: qgis.h:155
field comes from the underlying data provider of the vector layer (originIndex = index in provider's ...
Definition: qgsfield.h:180
bool mClosed
Set to true, as soon as the iterator is closed.
int targetFieldIndex
Join field index in the target layer.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:119
QgsVectorLayer * joinLayer
resolved pointer to the joined layer
bool isClosed() const
find out whether the iterator is still valid or closed already
QMap< const QgsVectorJoinInfo *, FetchJoinInfo > mFetchJoinInfo
information about joins used in the current select() statement.
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's data.
bool containsJoins() const
Quick way to test if there is any join at all.
void updateChangedAttributes(QgsFeature &f)
Update feature with uncommited attribute updates.
supports simplification of geometries on provider side according to a distance tolerance ...
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:293
void setGeometry(const QgsGeometry &geom)
Set this feature's geometry from another QgsGeometry object.
Definition: qgsfeature.cpp:104
QgsVectorLayerEditBuffer * editBuffer()
Buffer with uncommitted editing operations. Only valid after editing has been turned on...
void iteratorClosed()
to be called by from subclass in close()
void useAddedFeature(const QgsFeature &src, QgsFeature &f)
QgsFeatureRequest & setFilterFids(QgsFeatureIds fids)
Set feature ID that should be fetched.
void setFeatureId(QgsFeatureId id)
Sets the feature ID for this feature.
Definition: qgsfeature.cpp:81
const QgsVectorJoinInfo * joinInfo
cannonical source of information about the join
QgsAttributes attributes() const
Returns the feature's attributes.
Definition: qgsfeature.cpp:90
virtual int capabilities() const
Returns a bitmask containing the supported capabilities Note, some capabilities may change depending ...
bool needsGeometry() const
Returns true if the expression uses feature geometry for some computation.
void updateFeatureGeometry(QgsFeature &f)
Update feature with uncommited geometry updates.
virtual bool prepareSimplification(const QgsSimplifyMethod &simplifyMethod) override
Setup the simplification of geometries to fetch using the specified simplify method.
int fieldOriginIndex(int fieldIdx) const
Get field's origin index (its meaning is specific to each type of origin)
Definition: qgsfield.cpp:331
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()
Filter using a rectangle, no need to set NoGeometry.
int count() const
Return number of items.
Definition: qgsfield.cpp:283
No simplification is applied.
QGis::GeometryType geometryType() const
Returns point, line or polygon.
FilterType filterType() const
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:303
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:147
const QList< QgsField > & addedAttributes()
added attributes fields which are not commited
int indexFromName(const QString &name) const
Look up field's index from name. Returns -1 on error.
Definition: qgsfield.cpp:336
Partial snapshot of vector layer's state (only the members necessary for access to features) ...
QgsGeometry * geometry()
Get the geometry object associated with this feature.
Definition: qgsfeature.cpp:62
QgsVectorLayerFeatureSource(QgsVectorLayer *layer)
const QgsFeatureId & filterFid() const
int indexOffset
at what position the joined fields start
void useChangedAttributeFeature(QgsFeatureId fid, const QgsGeometry &geom, QgsFeature &f)
const QgsFeatureMap & addedFeatures()
New features which are not commited.
void setValid(bool validity)
Sets the validity of the feature.
Definition: qgsfeature.cpp:173
QMap< QgsFeatureId, QgsFeature > QgsFeatureMap
QgsFeatureRequest mRequest
A copy of the feature request.
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:236
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request) override
QMap< QgsFeatureId, QgsAttributeMap > QgsChangedAttributesMap
Definition: qgsfeature.h:360
QVector< QVariant > QgsAttributes
Definition: qgsfeature.h:106
virtual bool rewind() override
reset the iterator to the starting position
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.
const QgsGeometry * constGeometry() const
Gets a const pointer to the geometry object associated with this feature.
Definition: qgsfeature.cpp:68
FieldOrigin fieldOrigin(int fieldIdx) const
Get field's origin (value from an enumeration)
Definition: qgsfield.cpp:323
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
QgsMapLayer * mapLayer(QString theLayerId)
Retrieve a pointer to a loaded layer by id.
This class contains information about how to simplify geometries fetched from a QgsFeatureIterator.
void addJoinedAttributesCached(QgsFeature &f, const QVariant &joinValue) const
const QgsFields & pendingFields() const
returns field list in the to-be-committed state
Simplify using the Douglas-Peucker algorithm ensuring that the result is a valid geometry.
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request)=0
QgsVectorDataProvider * dataProvider()
Returns the data provider.
bool nextFeature(QgsFeature &f)
This is the base class for vector data providers.
QgsChangedAttributesMap mChangedAttributeValues
Geometry is not required. It may still be returned if e.g. required for a filter condition.
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:183
QgsFeatureRequest & setFlags(Flags flags)
Set flags that affect how features will be fetched.
QString joinLayerId
Source layer.
QgsAttributeList allAttributesList() const
Utility function to get list of attribute indexes.
Definition: qgsfield.cpp:366
MethodType methodType() const
Gets the simplification type.
void addVirtualAttributes(QgsFeature &f)
Adds attributes that don't source from the provider but are added inside QGIS Includes.
helper template that cares of two things: 1.
QgsExpression * filterExpression() const