QGIS API Documentation  2.7.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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  , mEditGeometrySimplifier( 0 )
91 {
92 
93  // prepare joins: may add more attributes to fetch (in order to allow join)
95  prepareJoins();
96 
98 
100 
101  // by default provider's request is the same
103 
105  {
106  // prepare list of attributes to match provider fields
107  QgsAttributeList providerSubset;
109  int nPendingFields = mSource->mFields.count();
110  for ( int i = 0; i < subset.count(); ++i )
111  {
112  int attrIndex = subset[i];
113  if ( attrIndex < 0 || attrIndex >= nPendingFields ) continue;
114  if ( mSource->mFields.fieldOrigin( attrIndex ) == QgsFields::OriginProvider )
115  providerSubset << mSource->mFields.fieldOriginIndex( attrIndex );
116  }
117  mProviderRequest.setSubsetOfAttributes( providerSubset );
118  }
119 
120  if ( mSource->mHasEditBuffer )
121  {
124  }
125 
126  if ( request.filterType() == QgsFeatureRequest::FilterFid )
127  {
128  mFetchedFid = false;
129  }
130  else // no filter or filter by rect
131  {
132  if ( mSource->mHasEditBuffer )
133  {
135  }
136  else
137  {
139  }
140 
142  }
143 
145  {
147  }
148 }
149 
150 
152 {
153  delete mEditGeometrySimplifier;
154  mEditGeometrySimplifier = NULL;
155 
156  qDeleteAll( mExpressionFieldInfo.values() );
157 
158  close();
159 }
160 
161 
162 
164 {
165  f.setValid( false );
166 
167  if ( mClosed )
168  return false;
169 
171  {
172  if ( mFetchedFid )
173  return false;
174  bool res = nextFeatureFid( f );
175  mFetchedFid = true;
176  return res;
177  }
178 
180  {
181  if ( fetchNextChangedGeomFeature( f ) )
182  return true;
183 
184  // no more changed geometries
185  }
186 
188  {
190  return true;
191 
192  // no more changed features
193  }
194 
195  while ( fetchNextAddedFeature( f ) )
196  {
197  return true;
198  }
199  // no more added features
200 
201  if ( mProviderIterator.isClosed() )
202  {
205  }
206 
207  while ( mProviderIterator.nextFeature( f ) )
208  {
209  if ( mFetchConsidered.contains( f.id() ) )
210  continue;
211 
212  // TODO[MD]: just one resize of attributes
213  f.setFields( &mSource->mFields );
214 
215  // update attributes
216  if ( mSource->mHasEditBuffer )
218 
219  if ( mHasVirtualAttributes )
221 
222  // update geometry
223  // TODO[MK]: FilterRect check after updating the geometry
226 
227  return true;
228  }
229  // no more provider features
230 
231  close();
232  return false;
233 }
234 
235 
236 
238 {
239  if ( mClosed )
240  return false;
241 
243  {
244  mFetchedFid = false;
245  }
246  else
247  {
250  }
251 
252  return true;
253 }
254 
256 {
257  if ( mClosed )
258  return false;
259 
261 
262  iteratorClosed();
263 
264  mClosed = true;
265  return true;
266 }
267 
268 
269 
270 
272 {
273  while ( mFetchAddedFeaturesIt-- != mSource->mAddedFeatures.constBegin() )
274  {
276 
277  if ( mFetchConsidered.contains( fid ) )
278  // must have changed geometry outside rectangle
279  continue;
280 
282  // skip features which are not accepted by the filter
283  continue;
284 
286 
287  return true;
288  }
289 
291  return false; // no more added features
292 }
293 
294 
296 {
297  f.setFeatureId( src.id() );
298  f.setValid( true );
299  f.setFields( &mSource->mFields );
300 
301  if ( src.geometry() && !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) )
302  {
303  f.setGeometry( *src.geometry() );
304 
305  // simplify the edited geometry using its simplifier configured
306  if ( mEditGeometrySimplifier )
307  {
308  QgsGeometry* geometry = f.geometry();
309  QGis::GeometryType geometryType = geometry->type();
310  if ( geometryType == QGis::Line || geometryType == QGis::Polygon ) mEditGeometrySimplifier->simplifyGeometry( geometry );
311  }
312  }
313 
314  // TODO[MD]: if subset set just some attributes
315 
316  f.setAttributes( src.attributes() );
317 
318  if ( mHasVirtualAttributes )
320 }
321 
322 
323 
325 {
326  // check if changed geometries are in rectangle
328  {
329  QgsFeatureId fid = mFetchChangedGeomIt.key();
330 
331  if ( mFetchConsidered.contains( fid ) )
332  // skip deleted features
333  continue;
334 
335  mFetchConsidered << fid;
336 
337  if ( !mFetchChangedGeomIt->intersects( mRequest.filterRect() ) )
338  // skip changed geometries not in rectangle and don't check again
339  continue;
340 
342 
343  // return complete feature
345  return true;
346  }
347 
348  return false; // no more changed geometries
349 }
350 
352 {
354  {
355  mFetchConsidered << f.id();
356 
358 
359  if ( mHasVirtualAttributes )
361 
363  {
364  if ( mRequest.filterExpression()->evaluate( &f ).toBool() )
365  {
366  return true;
367  }
368  }
369  else
370  {
371  return true;
372  }
373  }
374 
375  return false;
376 }
377 
378 
380 {
381  f.setFeatureId( fid );
382  f.setValid( true );
383  f.setFields( &mSource->mFields );
384 
386  {
387  f.setGeometry( geom );
388 
389  // simplify the edited geometry using its simplifier configured
390  if ( mEditGeometrySimplifier )
391  {
392  QgsGeometry* geometry = f.geometry();
393  QGis::GeometryType geometryType = geometry->type();
394  if ( geometryType == QGis::Line || geometryType == QGis::Polygon ) mEditGeometrySimplifier->simplifyGeometry( geometry );
395  }
396  }
397 
398  bool subsetAttrs = ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes );
399  if ( !subsetAttrs || ( subsetAttrs && mRequest.subsetOfAttributes().count() > 0 ) )
400  {
401  // retrieve attributes from provider
402  QgsFeature tmp;
403  //mDataProvider->featureAtId( fid, tmp, false, mFetchProvAttributes );
404  QgsFeatureRequest request;
406  if ( subsetAttrs )
407  {
409  }
411  if ( fi.nextFeature( tmp ) )
412  {
415  f.setAttributes( tmp.attributes() );
416  }
417  }
418 
420 }
421 
422 
423 
425 {
427 
430 }
431 
432 
433 
435 {
437  QgsAttributeList sourceJoinFields; // attributes that also need to be fetched from this layer in order to have joins working
438 
439  mFetchJoinInfo.clear();
440 
441  for ( QgsAttributeList::const_iterator attIt = fetchAttributes.constBegin(); attIt != fetchAttributes.constEnd(); ++attIt )
442  {
443  if ( !mSource->mFields.exists( *attIt ) )
444  continue;
445 
446  if ( mSource->mFields.fieldOrigin( *attIt ) != QgsFields::OriginJoin )
447  continue;
448 
449  int sourceLayerIndex;
450  const QgsVectorJoinInfo* joinInfo = mSource->mJoinBuffer->joinForFieldIndex( *attIt, mSource->mFields, sourceLayerIndex );
451  Q_ASSERT( joinInfo );
452 
453  QgsVectorLayer* joinLayer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( joinInfo->joinLayerId ) );
454  Q_ASSERT( joinLayer );
455 
456  if ( !mFetchJoinInfo.contains( joinLayer ) )
457  {
458  FetchJoinInfo info;
459  info.joinInfo = joinInfo;
460  info.joinLayer = joinLayer;
462 
463  if ( joinInfo->targetFieldName.isEmpty() )
464  info.targetField = joinInfo->targetFieldIndex; //for compatibility with 1.x
465  else
467 
468  if ( joinInfo->joinFieldName.isEmpty() )
469  info.joinField = joinInfo->joinFieldIndex; //for compatibility with 1.x
470  else
471  info.joinField = joinLayer->pendingFields().indexFromName( joinInfo->joinFieldName );
472 
473  // for joined fields, we always need to request the targetField from the provider too
474  if ( !fetchAttributes.contains( info.targetField ) )
475  sourceJoinFields << info.targetField;
476 
477  mFetchJoinInfo.insert( joinLayer, info );
478  }
479 
480  // store field source index - we'll need it when fetching from provider
481  mFetchJoinInfo[ joinLayer ].attributes.push_back( sourceLayerIndex );
482  }
483 
484  // add sourceJoinFields if we're using a subset
487 }
488 
490 {
491  const QList<QgsExpressionFieldBuffer::ExpressionField> exps = mSource->mExpressionFieldBuffer->expressions();
492 
493  for ( int i = 0; i < mSource->mFields.count(); i++ )
494  {
496  {
497  // Only prepare if there is no subset defined or the subset contains this field
499  || mRequest.subsetOfAttributes().contains( i ) )
500  {
501  int oi = mSource->mFields.fieldOriginIndex( i );
502  QgsExpression* exp = new QgsExpression( exps[oi].expression );
503  exp->prepare( mSource->mFields );
504  mExpressionFieldInfo.insert( i, exp );
505 
507  {
508  QgsAttributeList attrs;
509  Q_FOREACH ( const QString& col, exp->referencedColumns() )
510  {
511  attrs.append( mSource->mFields.fieldNameIndex( col ) );
512  }
513 
515  }
516 
517  if ( exp->needsGeometry() )
518  {
519  mRequest.setFlags( mRequest.flags() & ~QgsFeatureRequest::NoGeometry );
520  }
521  }
522  }
523  }
524 }
525 
527 {
528  QMap<QgsVectorLayer*, FetchJoinInfo>::const_iterator joinIt = mFetchJoinInfo.constBegin();
529  for ( ; joinIt != mFetchJoinInfo.constEnd(); ++joinIt )
530  {
531  const FetchJoinInfo& info = joinIt.value();
532  Q_ASSERT( joinIt.key() );
533 
534  QVariant targetFieldValue = f.attribute( info.targetField );
535  if ( !targetFieldValue.isValid() )
536  continue;
537 
538  const QHash< QString, QgsAttributes>& memoryCache = info.joinInfo->cachedAttributes;
539  if ( memoryCache.isEmpty() )
540  info.addJoinedAttributesDirect( f, targetFieldValue );
541  else
542  info.addJoinedAttributesCached( f, targetFieldValue );
543  }
544 }
545 
547 {
548  // make sure we have space for newly added attributes
549  f.attributes().resize( mSource->mFields.count() ); // Provider attrs count + joined attrs count + expression attrs count
550 
551  if ( !mFetchJoinInfo.isEmpty() )
552  addJoinedAttributes( f );
553 
554  if ( !mExpressionFieldInfo.isEmpty() )
555  {
556  QMap<int, QgsExpression*>::ConstIterator it = mExpressionFieldInfo.constBegin();
557 
558  for ( ; it != mExpressionFieldInfo.constEnd(); ++it )
559  {
560  QgsExpression* exp = it.value();
561  QVariant val = exp->evaluate( f );
562  mSource->mFields.at( it.key() ).convertCompatible( val );;
563  f.setAttribute( it.key(), val );
564  }
565  }
566 }
567 
569 {
570  delete mEditGeometrySimplifier;
571  mEditGeometrySimplifier = NULL;
572 
573  // setup simplification for edited geometries to fetch
575  {
576  mEditGeometrySimplifier = QgsSimplifyMethod::createGeometrySimplifier( simplifyMethod );
577  return mEditGeometrySimplifier != NULL;
578  }
579  return false;
580 }
581 
582 bool QgsVectorLayerFeatureIterator::providerCanSimplify( QgsSimplifyMethod::MethodType methodType ) const
583 {
584  Q_UNUSED( methodType );
585 #if 0
586  // TODO[MD]: after merge
587  QgsVectorDataProvider* provider = L->dataProvider();
588 
589  if ( provider && methodType != QgsSimplifyMethod::NoSimplification )
590  {
591  int capabilities = provider->capabilities();
592 
593  if ( methodType == QgsSimplifyMethod::OptimizeForRendering )
594  {
595  return ( capabilities & QgsVectorDataProvider::SimplifyGeometries );
596  }
597  else if ( methodType == QgsSimplifyMethod::PreserveTopology )
598  {
600  }
601  }
602 #endif
603  return false;
604 }
605 
606 
608 {
609  const QHash<QString, QgsAttributes>& memoryCache = joinInfo->cachedAttributes;
610  QHash<QString, QgsAttributes>::const_iterator it = memoryCache.find( joinValue.toString() );
611  if ( it == memoryCache.constEnd() )
612  return; // joined value not found -> leaving the attributes empty (null)
613 
614  int index = indexOffset;
615 
616  const QgsAttributes& featureAttributes = it.value();
617  for ( int i = 0; i < featureAttributes.count(); ++i )
618  {
619  f.setAttribute( index++, featureAttributes[i] );
620  }
621 }
622 
623 
624 
626 {
627  // no memory cache, query the joined values by setting substring
628  QString subsetString = joinLayer->dataProvider()->subsetString(); // provider might already have a subset string
629  QString bkSubsetString = subsetString;
630  if ( !subsetString.isEmpty() )
631  {
632  subsetString.prepend( "(" ).append( ") AND " );
633  }
634 
635  QString joinFieldName;
636  if ( joinInfo->joinFieldName.isEmpty() && joinInfo->joinFieldIndex >= 0 && joinInfo->joinFieldIndex < joinLayer->pendingFields().count() )
637  joinFieldName = joinLayer->pendingFields().field( joinInfo->joinFieldIndex ).name(); // for compatibility with 1.x
638  else
639  joinFieldName = joinInfo->joinFieldName;
640 
641  subsetString.append( QString( "\"%1\"" ).arg( joinFieldName ) );
642 
643  if ( joinValue.isNull() )
644  {
645  subsetString += " IS NULL";
646  }
647  else
648  {
649  QString v = joinValue.toString();
650  switch ( joinValue.type() )
651  {
652  case QVariant::Int:
653  case QVariant::LongLong:
654  case QVariant::Double:
655  break;
656 
657  default:
658  case QVariant::String:
659  v.replace( "'", "''" );
660  v.prepend( "'" ).append( "'" );
661  break;
662  }
663  subsetString += "=" + v;
664  }
665 
666  joinLayer->dataProvider()->setSubsetString( subsetString, false );
667 
668  // maybe user requested just a subset of layer's attributes
669  // so we do not have to cache everything
670  bool hasSubset = joinInfo->joinFieldNamesSubset();
671  QVector<int> subsetIndices;
672  if ( hasSubset )
673  subsetIndices = QgsVectorLayerJoinBuffer::joinSubsetIndices( joinLayer, *joinInfo->joinFieldNamesSubset() );
674 
675  // select (no geometry)
676  QgsFeatureRequest request;
678  request.setSubsetOfAttributes( attributes );
679  QgsFeatureIterator fi = joinLayer->getFeatures( request );
680 
681  // get first feature
682  QgsFeature fet;
683  if ( fi.nextFeature( fet ) )
684  {
685  int index = indexOffset;
686  const QgsAttributes& attr = fet.attributes();
687  if ( hasSubset )
688  {
689  for ( int i = 0; i < subsetIndices.count(); ++i )
690  f.setAttribute( index++, attr[ subsetIndices[i] ] );
691  }
692  else
693  {
694  // use all fields except for the one used for join (has same value as exiting field in target layer)
695  for ( int i = 0; i < attr.count(); ++i )
696  {
697  if ( i == joinField )
698  continue;
699 
700  f.setAttribute( index++, attr[i] );
701  }
702  }
703  }
704  else
705  {
706  // no suitable join feature found, keeping empty (null) attributes
707  }
708 
709  joinLayer->dataProvider()->setSubsetString( bkSubsetString, false );
710 }
711 
712 
713 
714 
716 {
717  QgsFeatureId featureId = mRequest.filterFid();
718 
719  // deleted already?
720  if ( mSource->mDeletedFeatureIds.contains( featureId ) )
721  return false;
722 
723  // has changed geometry?
724  if ( !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) && mSource->mChangedGeometries.contains( featureId ) )
725  {
726  useChangedAttributeFeature( featureId, mSource->mChangedGeometries[featureId], f );
727  return true;
728  }
729 
730  // added features
731  for ( QgsFeatureMap::ConstIterator iter = mSource->mAddedFeatures.constBegin(); iter != mSource->mAddedFeatures.constEnd(); ++iter )
732  {
733  if ( iter->id() == featureId )
734  {
735  useAddedFeature( *iter, f );
736  return true;
737  }
738  }
739 
740  // regular features
742  if ( fi.nextFeature( f ) )
743  {
744  if ( mSource->mHasEditBuffer )
746 
747  if ( mHasVirtualAttributes )
749 
750  return true;
751  }
752 
753  return false;
754 }
755 
757 {
758  QgsAttributes& attrs = f.attributes();
759 
760  // remove all attributes that will disappear - from higher indices to lower
761  for ( int idx = mSource->mDeletedAttributeIds.count() - 1; idx >= 0; --idx )
762  {
763  attrs.remove( mSource->mDeletedAttributeIds[idx] );
764  }
765 
766  // adjust size to accommodate added attributes
767  attrs.resize( attrs.count() + mSource->mAddedAttributes.count() );
768 
769  // update changed attributes
770  if ( mSource->mChangedAttributeValues.contains( f.id() ) )
771  {
773  for ( QgsAttributeMap::const_iterator it = map.begin(); it != map.end(); ++it )
774  attrs[it.key()] = it.value();
775  }
776 }
777 
779 {
780  if ( mSource->mChangedGeometries.contains( f.id() ) )
782 }
783 
QgsFeatureId id() const
Get the feature id for this feature.
Definition: qgsfeature.cpp:100
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:87
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:315
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.
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:98
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:317
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:208
QgsVectorLayerFeatureIterator(QgsVectorLayerFeatureSource *source, bool ownSource, const QgsFeatureRequest &request)
int joinFieldIndex
Join field index in the source layer.
QgsGeometry * geometry() const
Get the geometry object associated with this feature.
Definition: qgsfeature.cpp:112
static QgsMapLayerRegistry * instance()
Definition: qgssingleton.h:23
const QgsChangedAttributesMap & changedAttributeValues()
Changed attributes values which are not commited.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QGis::GeometryType type() const
Returns type of the vector.
const QgsAttributeList & subsetOfAttributes() const
void setAttributes(const QgsAttributes &attrs)
Definition: qgsfeature.h:144
bool setAttribute(int field, const QVariant &attr)
Set an attribute by id.
Definition: qgsfeature.cpp:190
QMap< int, QgsExpression * > mExpressionFieldInfo
GeometryType
Definition: qgis.h:155
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfield.h:227
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:113
const QList< ExpressionField > expressions() const
QgsVectorLayer * joinLayer
resolved pointer to the joined layer
bool isClosed() const
find out whether the iterator is still valid or closed already
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.
QMap< QgsVectorLayer *, FetchJoinInfo > mFetchJoinInfo
information about joins used in the current select() statement.
bool containsJoins() const
Quick way to test if there is any join at all.
void updateChangedAttributes(QgsFeature &f)
Update feature with uncommited attribute updates.
field comes from the underlying data provider of the vector layer (originIndex = index in provider's ...
Definition: qgsfield.h:179
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.h:220
void setGeometry(const QgsGeometry &geom)
Set this feature's geometry from another QgsGeometry object (deep copy)
Definition: qgsfeature.cpp:134
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)
Set the feature id for this feature.
Definition: qgsfeature.cpp:128
const QgsVectorJoinInfo * joinInfo
cannonical source of information about the join
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.h:236
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()
const QgsAttributes & attributes() const
Definition: qgsfeature.h:142
Filter using a rectangle, no need to set NoGeometry.
int count() const
Return number of items.
Definition: qgsfield.h:214
field is calculated from an expression
Definition: qgsfield.h:182
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
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:161
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.h:241
Partial snapshot of vector layer's state (only the members necessary for access to features) ...
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)
Set the validity of the feature.
Definition: qgsfeature.cpp:176
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.
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:230
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request) override
QMap< QgsFeatureId, QgsAttributeMap > QgsChangedAttributesMap
Definition: qgsfeature.h:312
QVector< QVariant > QgsAttributes
Definition: qgsfeature.h:100
FieldOrigin fieldOrigin(int fieldIdx) const
Get field's origin (value from an enumeration)
Definition: qgsfield.h:234
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.
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:30
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
field comes from a joined layer (originIndex / 1000 = index of the join, originIndex % 1000 = index w...
Definition: qgsfield.h:180
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.
Represents a vector layer which manages a vector based data sets.
const QgsAttributeList & deletedAttributeIds()
deleted attributes fields which are not commited.
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:220
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