QGIS API Documentation  2.13.0-Master
qgsvectorlayerfeatureiterator.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsvectorlayerfeatureiterator.cpp
3  ---------------------
4  begin : Dezember 2012
5  copyright : (C) 2012 by Martin Dobias
6  email : wonder dot sk at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
16 
18 #include "qgsgeometrysimplifier.h"
19 #include "qgsmaplayerregistry.h"
20 #include "qgssimplifymethod.h"
21 #include "qgsvectordataprovider.h"
23 #include "qgsvectorlayer.h"
25 #include "qgsexpressioncontext.h"
26 
28 {
30  mFields = layer->fields();
31  mJoinBuffer = layer->mJoinBuffer->clone();
32  mExpressionFieldBuffer = new QgsExpressionFieldBuffer( *layer->mExpressionFieldBuffer );
33 
34  mCanBeSimplified = layer->hasGeometryType() && layer->geometryType() != QGis::Point;
35 
36  mHasEditBuffer = layer->editBuffer();
37  if ( mHasEditBuffer )
38  {
39 #if 0
40  // TODO[MD]: after merge
41  if ( request.filterType() == QgsFeatureRequest::FilterFid )
42  {
43 
44  // only copy relevant parts
45  if ( L->editBuffer()->addedFeatures().contains( request.filterFid() ) )
46  mAddedFeatures.insert( request.filterFid(), L->editBuffer()->addedFeatures()[ request.filterFid()] );
47 
48  if ( L->editBuffer()->changedGeometries().contains( request.filterFid() ) )
49  mChangedGeometries.insert( request.filterFid(), L->editBuffer()->changedGeometries()[ request.filterFid()] );
50 
51  if ( L->editBuffer()->deletedFeatureIds().contains( request.filterFid() ) )
52  mDeletedFeatureIds.insert( request.filterFid() );
53 
54  if ( L->editBuffer()->changedAttributeValues().contains( request.filterFid() ) )
55  mChangedAttributeValues.insert( request.filterFid(), L->editBuffer()->changedAttributeValues()[ request.filterFid()] );
56 
57  if ( L->editBuffer()->changedAttributeValues().contains( request.filterFid() ) )
58  mChangedFeaturesRequest.setFilterFids( QgsFeatureIds() << request.filterFid() );
59  }
60  else
61  {
62 #endif
69 #if 0
70  }
71 #endif
72  }
73 }
74 
76 {
77  delete mJoinBuffer;
80 }
81 
83 {
84  // return feature iterator that does not own this source
85  return QgsFeatureIterator( new QgsVectorLayerFeatureIterator( this, false, request ) );
86 }
87 
88 
91  , mFetchedFid( false )
92  , mEditGeometrySimplifier( nullptr )
93 {
95 
96  // prepare joins: may add more attributes to fetch (in order to allow join)
98  prepareJoins();
99 
101 
102  // by default provider's request is the same
104 
106  {
107  // prepare list of attributes to match provider fields
108  QSet<int> providerSubset;
110  int nPendingFields = mSource->mFields.count();
111  Q_FOREACH ( int attrIndex, subset )
112  {
113  if ( attrIndex < 0 || attrIndex >= nPendingFields ) continue;
114  if ( mSource->mFields.fieldOrigin( attrIndex ) == QgsFields::OriginProvider )
115  providerSubset << mSource->mFields.fieldOriginIndex( attrIndex );
116  }
117 
118  // This is done in order to be prepared to do fallback order bys
119  // and be sure we have the required columns.
120  // TODO:
121  // It would be nicer to first check if we can compile the order by
122  // and only modify the subset if we cannot.
123  if ( !mProviderRequest.orderBy().isEmpty() )
124  {
125  Q_FOREACH ( const QString& attr, mProviderRequest.orderBy().usedAttributes() )
126  {
127  providerSubset << mSource->mFields.fieldNameIndex( attr );
128  }
129  }
130 
131  mProviderRequest.setSubsetOfAttributes( providerSubset.toList() );
132  }
133 
135  {
136  Q_FOREACH ( const QString& field, mProviderRequest.filterExpression()->referencedColumns() )
137  {
138  int idx = source->mFields.fieldNameIndex( field );
139 
140  // If there are fields in the expression which are not of origin provider, the provider will not be able to filter based on them.
141  // In this case we disable the expression filter.
142  if ( source->mFields.fieldOrigin( idx ) != QgsFields::OriginProvider )
143  {
145  }
146  }
147  }
148 
149  if ( mSource->mHasEditBuffer )
150  {
153  }
154 
155  if ( request.filterType() == QgsFeatureRequest::FilterFid )
156  {
157  mFetchedFid = false;
158  }
159  else // no filter or filter by rect
160  {
161  if ( mSource->mHasEditBuffer )
162  {
164  }
165  else
166  {
168  }
169 
171  }
172 
174  {
177  }
178 }
179 
180 
182 {
183  delete mEditGeometrySimplifier;
184  mEditGeometrySimplifier = nullptr;
185 
186  qDeleteAll( mExpressionFieldInfo );
187 
188  close();
189 }
190 
191 
192 
194 {
195  f.setValid( false );
196 
197  if ( mClosed )
198  return false;
199 
201  {
202  if ( mFetchedFid )
203  return false;
204  bool res = nextFeatureFid( f );
205  mFetchedFid = true;
206  return res;
207  }
208 
209  if ( !mRequest.filterRect().isNull() )
210  {
211  if ( fetchNextChangedGeomFeature( f ) )
212  return true;
213 
214  // no more changed geometries
215  }
216 
218  {
220  return true;
221 
222  // no more changed features
223  }
224 
225  while ( fetchNextAddedFeature( f ) )
226  {
227  return true;
228  }
229  // no more added features
230 
231  if ( mProviderIterator.isClosed() )
232  {
235  }
236 
237  while ( mProviderIterator.nextFeature( f ) )
238  {
239  if ( mFetchConsidered.contains( f.id() ) )
240  continue;
241 
242  // TODO[MD]: just one resize of attributes
243  f.setFields( mSource->mFields );
244 
245  // update attributes
246  if ( mSource->mHasEditBuffer )
248 
249  if ( mHasVirtualAttributes )
251 
253  {
254  //filtering by expression, and couldn't do it on the provider side
257  {
258  //feature did not match filter
259  continue;
260  }
261  }
262 
263  // update geometry
264  // TODO[MK]: FilterRect check after updating the geometry
267 
268  return true;
269  }
270  // no more provider features
271 
272  close();
273  return false;
274 }
275 
276 
277 
279 {
280  if ( mClosed )
281  return false;
282 
284  {
285  mFetchedFid = false;
286  }
287  else
288  {
291  }
292 
293  return true;
294 }
295 
297 {
298  if ( mClosed )
299  return false;
300 
302 
303  iteratorClosed();
304 
305  mClosed = true;
306  return true;
307 }
308 
309 
310 
311 
313 {
315  {
317 
318  if ( mFetchConsidered.contains( fid ) )
319  // must have changed geometry outside rectangle
320  continue;
321 
323  // skip features which are not accepted by the filter
324  continue;
325 
327 
328  return true;
329  }
330 
332  return false; // no more added features
333 }
334 
335 
337 {
338  f.setFeatureId( src.id() );
339  f.setValid( true );
340  f.setFields( mSource->mFields );
341 
343  {
344  f.setGeometry( new QgsGeometry( *src.constGeometry() ) );
345 
346  // simplify the edited geometry using its simplifier configured
347  if ( mEditGeometrySimplifier )
348  {
349  QgsGeometry* geometry = f.geometry();
350  QGis::GeometryType geometryType = geometry->type();
351  if ( geometryType == QGis::Line || geometryType == QGis::Polygon ) mEditGeometrySimplifier->simplifyGeometry( geometry );
352  }
353  }
354 
355  // TODO[MD]: if subset set just some attributes
356 
357  f.setAttributes( src.attributes() );
358 
359  if ( mHasVirtualAttributes )
361 }
362 
363 
364 
366 {
367  // check if changed geometries are in rectangle
369  {
370  QgsFeatureId fid = mFetchChangedGeomIt.key();
371 
372  if ( mFetchConsidered.contains( fid ) )
373  // skip deleted features
374  continue;
375 
376  mFetchConsidered << fid;
377 
378  if ( !mFetchChangedGeomIt->intersects( mRequest.filterRect() ) )
379  // skip changed geometries not in rectangle and don't check again
380  continue;
381 
383 
384  // return complete feature
386  return true;
387  }
388 
389  return false; // no more changed geometries
390 }
391 
393 {
395  {
396  if ( mFetchConsidered.contains( f.id() ) )
397  // skip deleted features and those already handled by the geometry
398  continue;
399 
400  mFetchConsidered << f.id();
401 
403 
404  if ( mHasVirtualAttributes )
406 
409  {
410  return true;
411  }
412  }
413 
414  return false;
415 }
416 
417 
419 {
420  f.setFeatureId( fid );
421  f.setValid( true );
422  f.setFields( mSource->mFields );
423 
425  {
426  f.setGeometry( geom );
427 
428  // simplify the edited geometry using its simplifier configured
429  if ( mEditGeometrySimplifier )
430  {
431  QgsGeometry* geometry = f.geometry();
432  QGis::GeometryType geometryType = geometry->type();
433  if ( geometryType == QGis::Line || geometryType == QGis::Polygon ) mEditGeometrySimplifier->simplifyGeometry( geometry );
434  }
435  }
436 
437  bool subsetAttrs = ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes );
438  if ( !subsetAttrs || !mRequest.subsetOfAttributes().isEmpty() )
439  {
440  // retrieve attributes from provider
441  QgsFeature tmp;
442  //mDataProvider->featureAtId( fid, tmp, false, mFetchProvAttributes );
443  QgsFeatureRequest request;
445  if ( subsetAttrs )
446  {
448  }
450  if ( fi.nextFeature( tmp ) )
451  {
454  f.setAttributes( tmp.attributes() );
455  }
456  }
457 
459 }
460 
461 
462 
464 {
466 
469 }
470 
471 
472 
474 {
476  QgsAttributeList sourceJoinFields; // attributes that also need to be fetched from this layer in order to have joins working
477 
478  mFetchJoinInfo.clear();
479 
480  for ( QgsAttributeList::const_iterator attIt = fetchAttributes.constBegin(); attIt != fetchAttributes.constEnd(); ++attIt )
481  {
482  if ( !mSource->mFields.exists( *attIt ) )
483  continue;
484 
485  if ( mSource->mFields.fieldOrigin( *attIt ) != QgsFields::OriginJoin )
486  continue;
487 
488  int sourceLayerIndex;
489  const QgsVectorJoinInfo* joinInfo = mSource->mJoinBuffer->joinForFieldIndex( *attIt, mSource->mFields, sourceLayerIndex );
490  Q_ASSERT( joinInfo );
491 
492  QgsVectorLayer* joinLayer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( joinInfo->joinLayerId ) );
493  Q_ASSERT( joinLayer );
494 
495  if ( !mFetchJoinInfo.contains( joinInfo ) )
496  {
497  FetchJoinInfo info;
498  info.joinInfo = joinInfo;
499  info.joinLayer = joinLayer;
501 
502  if ( joinInfo->targetFieldName.isEmpty() )
503  info.targetField = joinInfo->targetFieldIndex; //for compatibility with 1.x
504  else
506 
507  if ( joinInfo->joinFieldName.isEmpty() )
508  info.joinField = joinInfo->joinFieldIndex; //for compatibility with 1.x
509  else
510  info.joinField = joinLayer->fields().indexFromName( joinInfo->joinFieldName );
511 
512  // for joined fields, we always need to request the targetField from the provider too
513  if ( !fetchAttributes.contains( info.targetField ) )
514  sourceJoinFields << info.targetField;
515 
516  mFetchJoinInfo.insert( joinInfo, info );
517  }
518 
519  // store field source index - we'll need it when fetching from provider
520  mFetchJoinInfo[ joinInfo ].attributes.push_back( sourceLayerIndex );
521  }
522 
523  // add sourceJoinFields if we're using a subset
526 }
527 
529 {
531 
532  mExpressionContext.reset( new QgsExpressionContext() );
533  mExpressionContext->appendScope( QgsExpressionContextUtils::globalScope() );
534  mExpressionContext->appendScope( QgsExpressionContextUtils::projectScope() );
535  mExpressionContext->setFields( mSource->mFields );
536 
537  for ( int i = 0; i < mSource->mFields.count(); i++ )
538  {
540  {
541  // Only prepare if there is no subset defined or the subset contains this field
544  {
545  int oi = mSource->mFields.fieldOriginIndex( i );
546  QgsExpression* exp = new QgsExpression( exps[oi].cachedExpression );
547  exp->prepare( mExpressionContext.data() );
548  mExpressionFieldInfo.insert( i, exp );
549 
551  {
552  QgsAttributeList attrs;
553  Q_FOREACH ( const QString& col, exp->referencedColumns() )
554  {
555  attrs.append( mSource->mFields.fieldNameIndex( col ) );
556  }
557 
559  }
560 
561  if ( exp->needsGeometry() )
562  {
563  mRequest.setFlags( mRequest.flags() & ~QgsFeatureRequest::NoGeometry );
564  }
565  }
566  }
567  }
568 }
569 
571 {
573  for ( ; joinIt != mFetchJoinInfo.constEnd(); ++joinIt )
574  {
575  const FetchJoinInfo& info = joinIt.value();
576  Q_ASSERT( joinIt.key() );
577 
578  QVariant targetFieldValue = f.attribute( info.targetField );
579  if ( !targetFieldValue.isValid() )
580  continue;
581 
582  const QHash< QString, QgsAttributes>& memoryCache = info.joinInfo->cachedAttributes;
583  if ( memoryCache.isEmpty() )
584  info.addJoinedAttributesDirect( f, targetFieldValue );
585  else
586  info.addJoinedAttributesCached( f, targetFieldValue );
587  }
588 }
589 
591 {
592  // make sure we have space for newly added attributes
593  QgsAttributes attr = f.attributes();
594  attr.resize( mSource->mFields.count() ); // Provider attrs count + joined attrs count + expression attrs count
595  f.setAttributes( attr );
596 
597  if ( !mFetchJoinInfo.isEmpty() )
598  addJoinedAttributes( f );
599 
600  if ( !mExpressionFieldInfo.isEmpty() )
601  {
603 
604  for ( ; it != mExpressionFieldInfo.constEnd(); ++it )
605  {
606  QgsExpression* exp = it.value();
607  mExpressionContext->setFeature( f );
608  QVariant val = exp->evaluate( mExpressionContext.data() );
609  mSource->mFields.at( it.key() ).convertCompatible( val );
610  f.setAttribute( it.key(), val );
611  }
612  }
613 }
614 
616 {
617  delete mEditGeometrySimplifier;
618  mEditGeometrySimplifier = nullptr;
619 
620  // setup simplification for edited geometries to fetch
622  {
623  mEditGeometrySimplifier = QgsSimplifyMethod::createGeometrySimplifier( simplifyMethod );
624  return nullptr != mEditGeometrySimplifier;
625  }
626  return false;
627 }
628 
629 bool QgsVectorLayerFeatureIterator::providerCanSimplify( QgsSimplifyMethod::MethodType methodType ) const
630 {
631  Q_UNUSED( methodType );
632 #if 0
633  // TODO[MD]: after merge
634  QgsVectorDataProvider* provider = L->dataProvider();
635 
636  if ( provider && methodType != QgsSimplifyMethod::NoSimplification )
637  {
638  int capabilities = provider->capabilities();
639 
640  if ( methodType == QgsSimplifyMethod::OptimizeForRendering )
641  {
642  return ( capabilities & QgsVectorDataProvider::SimplifyGeometries );
643  }
644  else if ( methodType == QgsSimplifyMethod::PreserveTopology )
645  {
647  }
648  }
649 #endif
650  return false;
651 }
652 
653 
655 {
656  const QHash<QString, QgsAttributes>& memoryCache = joinInfo->cachedAttributes;
657  QHash<QString, QgsAttributes>::const_iterator it = memoryCache.find( joinValue.toString() );
658  if ( it == memoryCache.constEnd() )
659  return; // joined value not found -> leaving the attributes empty (null)
660 
661  int index = indexOffset;
662 
663  const QgsAttributes& featureAttributes = it.value();
664  for ( int i = 0; i < featureAttributes.count(); ++i )
665  {
666  f.setAttribute( index++, featureAttributes.at( i ) );
667  }
668 }
669 
670 
671 
673 {
674  // no memory cache, query the joined values by setting substring
675  QString subsetString = joinLayer->dataProvider()->subsetString(); // provider might already have a subset string
676  QString bkSubsetString = subsetString;
677  if ( !subsetString.isEmpty() )
678  {
679  subsetString.prepend( '(' ).append( ") AND " );
680  }
681 
682  QString joinFieldName;
683  if ( joinInfo->joinFieldName.isEmpty() && joinInfo->joinFieldIndex >= 0 && joinInfo->joinFieldIndex < joinLayer->fields().count() )
684  joinFieldName = joinLayer->fields().field( joinInfo->joinFieldIndex ).name(); // for compatibility with 1.x
685  else
686  joinFieldName = joinInfo->joinFieldName;
687 
688  subsetString.append( QString( "\"%1\"" ).arg( joinFieldName ) );
689 
690  if ( joinValue.isNull() )
691  {
692  subsetString += " IS NULL";
693  }
694  else
695  {
696  QString v = joinValue.toString();
697  switch ( joinValue.type() )
698  {
699  case QVariant::Int:
700  case QVariant::LongLong:
701  case QVariant::Double:
702  break;
703 
704  default:
705  case QVariant::String:
706  v.replace( '\'', "''" );
707  v.prepend( '\'' ).append( '\'' );
708  break;
709  }
710  subsetString += '=' + v;
711  }
712 
713  joinLayer->dataProvider()->setSubsetString( subsetString, false );
714 
715  // maybe user requested just a subset of layer's attributes
716  // so we do not have to cache everything
717  bool hasSubset = joinInfo->joinFieldNamesSubset();
718  QVector<int> subsetIndices;
719  if ( hasSubset )
720  subsetIndices = QgsVectorLayerJoinBuffer::joinSubsetIndices( joinLayer, *joinInfo->joinFieldNamesSubset() );
721 
722  // select (no geometry)
723  QgsFeatureRequest request;
725  request.setSubsetOfAttributes( attributes );
726  QgsFeatureIterator fi = joinLayer->getFeatures( request );
727 
728  // get first feature
729  QgsFeature fet;
730  if ( fi.nextFeature( fet ) )
731  {
732  int index = indexOffset;
733  QgsAttributes attr = fet.attributes();
734  if ( hasSubset )
735  {
736  for ( int i = 0; i < subsetIndices.count(); ++i )
737  f.setAttribute( index++, attr.at( subsetIndices.at( i ) ) );
738  }
739  else
740  {
741  // use all fields except for the one used for join (has same value as exiting field in target layer)
742  for ( int i = 0; i < attr.count(); ++i )
743  {
744  if ( i == joinField )
745  continue;
746 
747  f.setAttribute( index++, attr.at( i ) );
748  }
749  }
750  }
751  else
752  {
753  // no suitable join feature found, keeping empty (null) attributes
754  }
755 
756  joinLayer->dataProvider()->setSubsetString( bkSubsetString, false );
757 }
758 
759 
760 
761 
763 {
764  QgsFeatureId featureId = mRequest.filterFid();
765 
766  // deleted already?
767  if ( mSource->mDeletedFeatureIds.contains( featureId ) )
768  return false;
769 
770  // has changed geometry?
772  {
773  useChangedAttributeFeature( featureId, mSource->mChangedGeometries[featureId], f );
774  return true;
775  }
776 
777  // added features
779  {
780  if ( iter->id() == featureId )
781  {
782  useAddedFeature( *iter, f );
783  return true;
784  }
785  }
786 
787  // regular features
789  if ( fi.nextFeature( f ) )
790  {
791  if ( mSource->mHasEditBuffer )
793 
794  if ( mHasVirtualAttributes )
796 
797  return true;
798  }
799 
800  return false;
801 }
802 
804 {
805  QgsAttributes attrs = f.attributes();
806 
807  // remove all attributes that will disappear - from higher indices to lower
808  for ( int idx = mSource->mDeletedAttributeIds.count() - 1; idx >= 0; --idx )
809  {
810  attrs.remove( mSource->mDeletedAttributeIds[idx] );
811  }
812 
813  // adjust size to accommodate added attributes
814  attrs.resize( attrs.count() + mSource->mAddedAttributes.count() );
815 
816  // update changed attributes
818  {
820  for ( QgsAttributeMap::const_iterator it = map.begin(); it != map.end(); ++it )
821  attrs[it.key()] = it.value();
822  }
823  f.setAttributes( attrs );
824 }
825 
827 {
828  if ( mSource->mChangedGeometries.contains( f.id() ) )
830 }
831 
832 bool QgsVectorLayerFeatureIterator::prepareOrderBy( const QList<QgsFeatureRequest::OrderByClause>& orderBys )
833 {
834  Q_UNUSED( orderBys );
835  return true;
836 }
837 
QgsFeatureId id() const
Get the feature ID for this feature.
Definition: qgsfeature.cpp:65
const QgsGeometryMap & changedGeometries()
Changed geometries which are not commited.
QgsAbstractFeatureSource * mProviderFeatureSource
Class for parsing and evaluation of expressions (formerly called "search strings").
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:431
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:197
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:111
Q_DECL_DEPRECATED QVariant evaluate(const QgsFeature *f)
Evaluate the feature and return the result.
QgsFeatureId filterFid() const
Get the feature ID that should be fetched.
QgsFeatureMap::ConstIterator mFetchAddedFeaturesIt
QgsGeometryMap::ConstIterator mFetchChangedGeomIt
const QgsRectangle & filterRect() const
Get the rectangle from which features will be taken.
Q_DECL_DEPRECATED bool prepare(const QgsFields &fields)
Get the expression ready for evaluation - find out column indexes.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeature.h:433
QgsFields fields() const
Returns the list of fields of this layer.
Supports simplification of geometries on provider side according to a distance tolerance.
int fieldNameIndex(const QString &fieldName) const
Look up field&#39;s index from name also looks up case-insensitive if there is no match otherwise...
Definition: qgsfield.cpp:446
QString & prepend(QChar ch)
QgsVectorLayerFeatureIterator(QgsVectorLayerFeatureSource *source, bool ownSource, const QgsFeatureRequest &request)
QgsExpressionContext * expressionContext()
Returns the expression context used to evaluate filter expressions.
int joinFieldIndex
Join field index in the source layer.
const_iterator constBegin() const
const QgsChangedAttributesMap & changedAttributeValues()
Changed attributes values which are not commited.
bool isNull() const
test if the rectangle is null (all coordinates zero or after call to setMinimal()).
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:76
const QgsAttributeList & subsetOfAttributes() const
Return the subset of attributes which at least need to be fetched.
void setAttributes(const QgsAttributes &attrs)
Sets the feature&#39;s attributes.
Definition: qgsfeature.cpp:115
bool setAttribute(int field, const QVariant &attr)
Set an attribute&#39;s value by field index.
Definition: qgsfeature.cpp:222
QMap< int, QgsExpression * > mExpressionFieldInfo
field comes from the underlying data provider of the vector layer (originIndex = index in provider&#39;s ...
Definition: qgsfield.h:196
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:187
QgsVectorLayer * joinLayer
resolved pointer to the joined layer
bool isClosed() const
find out whether the iterator is still valid or closed already
QgsMapLayer * mapLayer(const QString &theLayerId)
Retrieve a pointer to a loaded layer by id.
QMap< const QgsVectorJoinInfo *, FetchJoinInfo > mFetchJoinInfo
Information about joins used in the current select() statement.
void reset(T *other)
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&#39;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:373
void setGeometry(const QgsGeometry &geom)
Set this feature&#39;s geometry from another QgsGeometry object.
Definition: qgsfeature.cpp:124
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)
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context...
void resize(int size)
const_iterator constEnd() const
void setFeatureId(QgsFeatureId id)
Sets the feature ID for this feature.
Definition: qgsfeature.cpp:101
bool isNull() const
const Key & key() const
const QgsVectorJoinInfo * joinInfo
cannonical source of information about the join
QgsAttributes attributes() const
Returns the feature&#39;s attributes.
Definition: qgsfeature.cpp:110
virtual int capabilities() const
Returns a bitmask containing the supported capabilities Note, some capabilities may change depending ...
QgsFeatureRequest & disableFilter()
Disables filter conditions.
bool needsGeometry() const
Returns true if the expression uses feature geometry for some computation.
void updateFeatureGeometry(QgsFeature &f)
Update feature with uncommited geometry updates.
bool isEmpty() const
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
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&#39;s origin index (its meaning is specific to each type of origin)
Definition: qgsfield.cpp:417
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()
QSet< QString > CORE_EXPORT usedAttributes() const
Returns a set of used attributes.
const T & value() const
int count() const
Return number of items.
Definition: qgsfield.cpp:363
No simplification is applied.
QGis::GeometryType geometryType() const
Returns point, line or polygon.
FilterType filterType() const
Return the filter type which is currently set on this request.
QgsFeatureRequest & setFlags(const QgsFeatureRequest::Flags &flags)
Set flags that affect how features will be fetched.
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:383
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:173
const QList< QgsField > & addedAttributes()
Added attributes fields which are not commited.
void setFields(const QgsFields &fields)
Convenience function for setting a fields for the context.
int indexFromName(const QString &name) const
Look up field&#39;s index from name. Returns -1 on error.
Definition: qgsfield.cpp:422
T * data() const
const T value(const Key &key) const
iterator find(const Key &key)
Partial snapshot of vector layer&#39;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:76
QgsVectorLayerFeatureSource(QgsVectorLayer *layer)
bool contains(const T &value) 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:204
QMap< QgsFeatureId, QgsFeature > QgsFeatureMap
QString & replace(int position, int n, QChar after)
QgsFeatureRequest mRequest
A copy of the feature request.
const T & at(int i) const
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:271
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Set feature IDs that should be fetched.
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request) override
Get an iterator for features matching the specified request.
QMap< QgsFeatureId, QgsAttributeMap > QgsChangedAttributesMap
Definition: qgsfeature.h:428
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:82
FieldOrigin fieldOrigin(int fieldIdx) const
Get field&#39;s origin (value from an enumeration)
Definition: qgsfield.cpp:409
OrderBy orderBy() const
Return a list of order by clauses specified for this feature request.
static QgsAbstractGeometrySimplifier * createGeometrySimplifier(const QgsSimplifyMethod &simplifyMethod)
Creates a geometry simplifier according to specified method.
Join information prepared for fast attribute id mapping in QgsVectorLayerJoinBuffer::updateFeatureAtt...
qint64 QgsFeatureId
Definition: qgsfeature.h:31
QList< T > toList() const
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
static QgsExpressionContextScope * projectScope()
Creates a new scope which contains variables and functions relating to the current QGIS project...
Simplify using the Douglas-Peucker algorithm ensuring that the result is a valid geometry.
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request)=0
Get an iterator for features matching the specified request.
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:115
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:199
QString toString() const
QString joinLayerId
Source layer.
QgsAttributeList allAttributesList() const
Utility function to get list of attribute indexes.
Definition: qgsfield.cpp:463
MethodType methodType() const
Gets the simplification type.
void addVirtualAttributes(QgsFeature &f)
Adds attributes that don&#39;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
Returns the filter expression if set.