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 
89  : QgsAbstractFeatureIteratorFromSource( source, ownSource, request )
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.
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
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()
Returns type of the vector.
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request)
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 ...
virtual bool fetchFeature(QgsFeature &feature)
fetch next feature, return true on success
void updateFeatureGeometry(QgsFeature &f)
Update feature with uncommited geometry updates.
int fieldOriginIndex(int fieldIdx) const
Get field's origin index (its meaning is specific to each type of origin)
Definition: qgsfield.h:236
QStringList referencedColumns()
Get list of columns referenced by the expression.
virtual bool close()
end of iterating: free the resources / lock
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
virtual bool rewind()
reset the iterator to the starting position
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) ...
bool needsGeometry()
Returns true if the expression uses feature geometry for some computation.
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.
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:230
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
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.
virtual bool prepareSimplification(const QgsSimplifyMethod &simplifyMethod)
Setup the simplification of geometries to fetch using the specified simplify method.
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