QGIS API Documentation  2.9.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  , 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 
302  if ( src.geometry() && !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) )
303  {
304  f.setGeometry( *src.geometry() );
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  f.attributes().resize( mSource->mFields.count() ); // Provider attrs count + joined attrs count + expression attrs count
551 
552  if ( !mFetchJoinInfo.isEmpty() )
553  addJoinedAttributes( f );
554 
555  if ( !mExpressionFieldInfo.isEmpty() )
556  {
557  QMap<int, QgsExpression*>::ConstIterator it = mExpressionFieldInfo.constBegin();
558 
559  for ( ; it != mExpressionFieldInfo.constEnd(); ++it )
560  {
561  QgsExpression* exp = it.value();
562  QVariant val = exp->evaluate( f );
563  mSource->mFields.at( it.key() ).convertCompatible( val );;
564  f.setAttribute( it.key(), val );
565  }
566  }
567 }
568 
570 {
571  delete mEditGeometrySimplifier;
572  mEditGeometrySimplifier = NULL;
573 
574  // setup simplification for edited geometries to fetch
576  {
577  mEditGeometrySimplifier = QgsSimplifyMethod::createGeometrySimplifier( simplifyMethod );
578  return mEditGeometrySimplifier != NULL;
579  }
580  return false;
581 }
582 
583 bool QgsVectorLayerFeatureIterator::providerCanSimplify( QgsSimplifyMethod::MethodType methodType ) const
584 {
585  Q_UNUSED( methodType );
586 #if 0
587  // TODO[MD]: after merge
588  QgsVectorDataProvider* provider = L->dataProvider();
589 
590  if ( provider && methodType != QgsSimplifyMethod::NoSimplification )
591  {
592  int capabilities = provider->capabilities();
593 
594  if ( methodType == QgsSimplifyMethod::OptimizeForRendering )
595  {
596  return ( capabilities & QgsVectorDataProvider::SimplifyGeometries );
597  }
598  else if ( methodType == QgsSimplifyMethod::PreserveTopology )
599  {
601  }
602  }
603 #endif
604  return false;
605 }
606 
607 
609 {
610  const QHash<QString, QgsAttributes>& memoryCache = joinInfo->cachedAttributes;
611  QHash<QString, QgsAttributes>::const_iterator it = memoryCache.find( joinValue.toString() );
612  if ( it == memoryCache.constEnd() )
613  return; // joined value not found -> leaving the attributes empty (null)
614 
615  int index = indexOffset;
616 
617  const QgsAttributes& featureAttributes = it.value();
618  for ( int i = 0; i < featureAttributes.count(); ++i )
619  {
620  f.setAttribute( index++, featureAttributes[i] );
621  }
622 }
623 
624 
625 
627 {
628  // no memory cache, query the joined values by setting substring
629  QString subsetString = joinLayer->dataProvider()->subsetString(); // provider might already have a subset string
630  QString bkSubsetString = subsetString;
631  if ( !subsetString.isEmpty() )
632  {
633  subsetString.prepend( "(" ).append( ") AND " );
634  }
635 
636  QString joinFieldName;
637  if ( joinInfo->joinFieldName.isEmpty() && joinInfo->joinFieldIndex >= 0 && joinInfo->joinFieldIndex < joinLayer->pendingFields().count() )
638  joinFieldName = joinLayer->pendingFields().field( joinInfo->joinFieldIndex ).name(); // for compatibility with 1.x
639  else
640  joinFieldName = joinInfo->joinFieldName;
641 
642  subsetString.append( QString( "\"%1\"" ).arg( joinFieldName ) );
643 
644  if ( joinValue.isNull() )
645  {
646  subsetString += " IS NULL";
647  }
648  else
649  {
650  QString v = joinValue.toString();
651  switch ( joinValue.type() )
652  {
653  case QVariant::Int:
654  case QVariant::LongLong:
655  case QVariant::Double:
656  break;
657 
658  default:
659  case QVariant::String:
660  v.replace( "'", "''" );
661  v.prepend( "'" ).append( "'" );
662  break;
663  }
664  subsetString += "=" + v;
665  }
666 
667  joinLayer->dataProvider()->setSubsetString( subsetString, false );
668 
669  // maybe user requested just a subset of layer's attributes
670  // so we do not have to cache everything
671  bool hasSubset = joinInfo->joinFieldNamesSubset();
672  QVector<int> subsetIndices;
673  if ( hasSubset )
674  subsetIndices = QgsVectorLayerJoinBuffer::joinSubsetIndices( joinLayer, *joinInfo->joinFieldNamesSubset() );
675 
676  // select (no geometry)
677  QgsFeatureRequest request;
679  request.setSubsetOfAttributes( attributes );
680  QgsFeatureIterator fi = joinLayer->getFeatures( request );
681 
682  // get first feature
683  QgsFeature fet;
684  if ( fi.nextFeature( fet ) )
685  {
686  int index = indexOffset;
687  const QgsAttributes& attr = fet.attributes();
688  if ( hasSubset )
689  {
690  for ( int i = 0; i < subsetIndices.count(); ++i )
691  f.setAttribute( index++, attr[ subsetIndices[i] ] );
692  }
693  else
694  {
695  // use all fields except for the one used for join (has same value as exiting field in target layer)
696  for ( int i = 0; i < attr.count(); ++i )
697  {
698  if ( i == joinField )
699  continue;
700 
701  f.setAttribute( index++, attr[i] );
702  }
703  }
704  }
705  else
706  {
707  // no suitable join feature found, keeping empty (null) attributes
708  }
709 
710  joinLayer->dataProvider()->setSubsetString( bkSubsetString, false );
711 }
712 
713 
714 
715 
717 {
718  QgsFeatureId featureId = mRequest.filterFid();
719 
720  // deleted already?
721  if ( mSource->mDeletedFeatureIds.contains( featureId ) )
722  return false;
723 
724  // has changed geometry?
725  if ( !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) && mSource->mChangedGeometries.contains( featureId ) )
726  {
727  useChangedAttributeFeature( featureId, mSource->mChangedGeometries[featureId], f );
728  return true;
729  }
730 
731  // added features
732  for ( QgsFeatureMap::ConstIterator iter = mSource->mAddedFeatures.constBegin(); iter != mSource->mAddedFeatures.constEnd(); ++iter )
733  {
734  if ( iter->id() == featureId )
735  {
736  useAddedFeature( *iter, f );
737  return true;
738  }
739  }
740 
741  // regular features
743  if ( fi.nextFeature( f ) )
744  {
745  if ( mSource->mHasEditBuffer )
747 
748  if ( mHasVirtualAttributes )
750 
751  return true;
752  }
753 
754  return false;
755 }
756 
758 {
759  QgsAttributes& attrs = f.attributes();
760 
761  // remove all attributes that will disappear - from higher indices to lower
762  for ( int idx = mSource->mDeletedAttributeIds.count() - 1; idx >= 0; --idx )
763  {
764  attrs.remove( mSource->mDeletedAttributeIds[idx] );
765  }
766 
767  // adjust size to accommodate added attributes
768  attrs.resize( attrs.count() + mSource->mAddedAttributes.count() );
769 
770  // update changed attributes
771  if ( mSource->mChangedAttributeValues.contains( f.id() ) )
772  {
774  for ( QgsAttributeMap::const_iterator it = map.begin(); it != map.end(); ++it )
775  attrs[it.key()] = it.value();
776  }
777 }
778 
780 {
781  if ( mSource->mChangedGeometries.contains( f.id() ) )
783 }
784 
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:234
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
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.
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:239
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
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.
FieldOrigin fieldOrigin(int fieldIdx) const
Get field's origin (value from an enumeration)
Definition: qgsfield.cpp:218
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:246
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