QGIS API Documentation  2.10.1-Pisa
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups 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
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 {
94 
95  // prepare joins: may add more attributes to fetch (in order to allow join)
97  prepareJoins();
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 {
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 
302  {
303  f.setGeometry( new QgsGeometry( *src.constGeometry() ) );
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( joinInfo ) )
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( joinInfo, info );
478  }
479 
480  // store field source index - we'll need it when fetching from provider
481  mFetchJoinInfo[ joinInfo ].attributes.push_back( sourceLayerIndex );
482  }
483 
484  // add sourceJoinFields if we're using a subset
487 }
488 
490 {
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
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 {
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  QgsAttributes attr = f.attributes();
550  attr.resize( mSource->mFields.count() ); // Provider attrs count + joined attrs count + expression attrs count
551  f.setAttributes( attr );
552 
553  if ( !mFetchJoinInfo.isEmpty() )
554  addJoinedAttributes( f );
555 
556  if ( !mExpressionFieldInfo.isEmpty() )
557  {
559 
560  for ( ; it != mExpressionFieldInfo.constEnd(); ++it )
561  {
562  QgsExpression* exp = it.value();
563  QVariant val = exp->evaluate( f );
564  mSource->mFields.at( it.key() ).convertCompatible( val );;
565  f.setAttribute( it.key(), val );
566  }
567  }
568 }
569 
571 {
572  delete mEditGeometrySimplifier;
573  mEditGeometrySimplifier = NULL;
574 
575  // setup simplification for edited geometries to fetch
577  {
578  mEditGeometrySimplifier = QgsSimplifyMethod::createGeometrySimplifier( simplifyMethod );
579  return mEditGeometrySimplifier != NULL;
580  }
581  return false;
582 }
583 
584 bool QgsVectorLayerFeatureIterator::providerCanSimplify( QgsSimplifyMethod::MethodType methodType ) const
585 {
586  Q_UNUSED( methodType );
587 #if 0
588  // TODO[MD]: after merge
589  QgsVectorDataProvider* provider = L->dataProvider();
590 
591  if ( provider && methodType != QgsSimplifyMethod::NoSimplification )
592  {
593  int capabilities = provider->capabilities();
594 
595  if ( methodType == QgsSimplifyMethod::OptimizeForRendering )
596  {
597  return ( capabilities & QgsVectorDataProvider::SimplifyGeometries );
598  }
599  else if ( methodType == QgsSimplifyMethod::PreserveTopology )
600  {
602  }
603  }
604 #endif
605  return false;
606 }
607 
608 
610 {
612  QHash<QString, QgsAttributes>::const_iterator it = memoryCache.find( joinValue.toString() );
613  if ( it == memoryCache.constEnd() )
614  return; // joined value not found -> leaving the attributes empty (null)
615 
616  int index = indexOffset;
617 
618  const QgsAttributes& featureAttributes = it.value();
619  for ( int i = 0; i < featureAttributes.count(); ++i )
620  {
621  f.setAttribute( index++, featureAttributes[i] );
622  }
623 }
624 
625 
626 
628 {
629  // no memory cache, query the joined values by setting substring
630  QString subsetString = joinLayer->dataProvider()->subsetString(); // provider might already have a subset string
631  QString bkSubsetString = subsetString;
632  if ( !subsetString.isEmpty() )
633  {
634  subsetString.prepend( "(" ).append( ") AND " );
635  }
636 
637  QString joinFieldName;
638  if ( joinInfo->joinFieldName.isEmpty() && joinInfo->joinFieldIndex >= 0 && joinInfo->joinFieldIndex < joinLayer->pendingFields().count() )
639  joinFieldName = joinLayer->pendingFields().field( joinInfo->joinFieldIndex ).name(); // for compatibility with 1.x
640  else
641  joinFieldName = joinInfo->joinFieldName;
642 
643  subsetString.append( QString( "\"%1\"" ).arg( joinFieldName ) );
644 
645  if ( joinValue.isNull() )
646  {
647  subsetString += " IS NULL";
648  }
649  else
650  {
651  QString v = joinValue.toString();
652  switch ( joinValue.type() )
653  {
654  case QVariant::Int:
655  case QVariant::LongLong:
656  case QVariant::Double:
657  break;
658 
659  default:
660  case QVariant::String:
661  v.replace( "'", "''" );
662  v.prepend( "'" ).append( "'" );
663  break;
664  }
665  subsetString += "=" + v;
666  }
667 
668  joinLayer->dataProvider()->setSubsetString( subsetString, false );
669 
670  // maybe user requested just a subset of layer's attributes
671  // so we do not have to cache everything
672  bool hasSubset = joinInfo->joinFieldNamesSubset();
673  QVector<int> subsetIndices;
674  if ( hasSubset )
675  subsetIndices = QgsVectorLayerJoinBuffer::joinSubsetIndices( joinLayer, *joinInfo->joinFieldNamesSubset() );
676 
677  // select (no geometry)
678  QgsFeatureRequest request;
680  request.setSubsetOfAttributes( attributes );
681  QgsFeatureIterator fi = joinLayer->getFeatures( request );
682 
683  // get first feature
684  QgsFeature fet;
685  if ( fi.nextFeature( fet ) )
686  {
687  int index = indexOffset;
688  QgsAttributes attr = fet.attributes();
689  if ( hasSubset )
690  {
691  for ( int i = 0; i < subsetIndices.count(); ++i )
692  f.setAttribute( index++, attr[ subsetIndices[i] ] );
693  }
694  else
695  {
696  // use all fields except for the one used for join (has same value as exiting field in target layer)
697  for ( int i = 0; i < attr.count(); ++i )
698  {
699  if ( i == joinField )
700  continue;
701 
702  f.setAttribute( index++, attr[i] );
703  }
704  }
705  }
706  else
707  {
708  // no suitable join feature found, keeping empty (null) attributes
709  }
710 
711  joinLayer->dataProvider()->setSubsetString( bkSubsetString, false );
712 }
713 
714 
715 
716 
718 {
719  QgsFeatureId featureId = mRequest.filterFid();
720 
721  // deleted already?
722  if ( mSource->mDeletedFeatureIds.contains( featureId ) )
723  return false;
724 
725  // has changed geometry?
727  {
728  useChangedAttributeFeature( featureId, mSource->mChangedGeometries[featureId], f );
729  return true;
730  }
731 
732  // added features
734  {
735  if ( iter->id() == featureId )
736  {
737  useAddedFeature( *iter, f );
738  return true;
739  }
740  }
741 
742  // regular features
744  if ( fi.nextFeature( f ) )
745  {
746  if ( mSource->mHasEditBuffer )
748 
749  if ( mHasVirtualAttributes )
751 
752  return true;
753  }
754 
755  return false;
756 }
757 
759 {
760  QgsAttributes attrs = f.attributes();
761 
762  // remove all attributes that will disappear - from higher indices to lower
763  for ( int idx = mSource->mDeletedAttributeIds.count() - 1; idx >= 0; --idx )
764  {
765  attrs.remove( mSource->mDeletedAttributeIds[idx] );
766  }
767 
768  // adjust size to accommodate added attributes
769  attrs.resize( attrs.count() + mSource->mAddedAttributes.count() );
770 
771  // update changed attributes
773  {
775  for ( QgsAttributeMap::const_iterator it = map.begin(); it != map.end(); ++it )
776  attrs[it.key()] = it.value();
777  }
778  f.setAttributes( attrs );
779 }
780 
782 {
783  if ( mSource->mChangedGeometries.contains( f.id() ) )
785 }
786 
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:406
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:181
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:155
QList< T > values() const
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:408
supports simplification of geometries on provider side according to a distance tolerance ...
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
QString & prepend(QChar ch)
QgsVectorLayerFeatureIterator(QgsVectorLayerFeatureSource *source, bool ownSource, const QgsFeatureRequest &request)
int joinFieldIndex
Join field index in the source layer.
const_iterator constBegin() const
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 geometry as a QGis::GeometryType.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:75
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
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.
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:162
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.
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's data.
bool containsJoins() const
Quick way to test if there is any join at all.
QList< Key > keys() const
void updateChangedAttributes(QgsFeature &f)
Update feature with uncommited attribute updates.
QgsFeatureRequest & setFilterFid(QgsFeatureId fid)
Set feature ID that should be fetched.
Simplify using the map2pixel data to optimize the rendering of geometries.
bool exists(int i) const
Return if a field index is valid.
Definition: qgsfield.cpp: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...
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)
QgsFeatureRequest & setFilterFids(QgsFeatureIds fids)
Set feature ID that should be fetched.
void resize(int size)
const_iterator constEnd() const
void setFeatureId(QgsFeatureId id)
Sets the feature ID for this feature.
Definition: qgsfeature.cpp:81
bool isNull() const
const Key & key() const
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.
bool isEmpty() const
const_iterator constEnd() const
void remove(int i)
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()
const T & value() const
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
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:303
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: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
const T value(const Key &key) const
iterator find(const Key &key)
Partial snapshot of vector layer'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:62
QgsVectorLayerFeatureSource(QgsVectorLayer *layer)
bool contains(const T &value) const
const QgsFeatureId & filterFid() 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
void setValid(bool validity)
Sets the validity of the feature.
Definition: qgsfeature.cpp:173
QMap< QgsFeatureId, QgsFeature > QgsFeatureMap
QString & replace(int position, int n, QChar after)
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:403
bool isEmpty() const
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.
int count(const T &value) const
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...
bool toBool() const
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.
iterator insert(const Key &key, const T &value)
void addJoinedAttributesCached(QgsFeature &f, const QVariant &joinValue) const
bool isEmpty() 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.
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:109
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 toString() const
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.
const T value(const Key &key) const
QgsExpression * filterExpression() const