QGIS API Documentation  2.12.0-Lyon
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( 0 )
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  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 
122  {
123  Q_FOREACH ( const QString& field, mProviderRequest.filterExpression()->referencedColumns() )
124  {
125  int idx = source->mFields.fieldNameIndex( field );
126 
127  // If there are fields in the expression which are not of origin provider, the provider will not be able to filter based on them.
128  // In this case we disable the expression filter.
129  if ( source->mFields.fieldOrigin( idx ) != QgsFields::OriginProvider )
130  {
132  }
133  }
134  }
135 
136  if ( mSource->mHasEditBuffer )
137  {
140  }
141 
142  if ( request.filterType() == QgsFeatureRequest::FilterFid )
143  {
144  mFetchedFid = false;
145  }
146  else // no filter or filter by rect
147  {
148  if ( mSource->mHasEditBuffer )
149  {
151  }
152  else
153  {
155  }
156 
158  }
159 
161  {
164  }
165 }
166 
167 
169 {
170  delete mEditGeometrySimplifier;
171  mEditGeometrySimplifier = NULL;
172 
173  qDeleteAll( mExpressionFieldInfo );
174 
175  close();
176 }
177 
178 
179 
181 {
182  f.setValid( false );
183 
184  if ( mClosed )
185  return false;
186 
188  {
189  if ( mFetchedFid )
190  return false;
191  bool res = nextFeatureFid( f );
192  mFetchedFid = true;
193  return res;
194  }
195 
196  if ( !mRequest.filterRect().isNull() )
197  {
198  if ( fetchNextChangedGeomFeature( f ) )
199  return true;
200 
201  // no more changed geometries
202  }
203 
205  {
207  return true;
208 
209  // no more changed features
210  }
211 
212  while ( fetchNextAddedFeature( f ) )
213  {
214  return true;
215  }
216  // no more added features
217 
218  if ( mProviderIterator.isClosed() )
219  {
222  }
223 
224  while ( mProviderIterator.nextFeature( f ) )
225  {
226  if ( mFetchConsidered.contains( f.id() ) )
227  continue;
228 
229  // TODO[MD]: just one resize of attributes
230  f.setFields( mSource->mFields );
231 
232  // update attributes
233  if ( mSource->mHasEditBuffer )
235 
236  if ( mHasVirtualAttributes )
238 
239  // update geometry
240  // TODO[MK]: FilterRect check after updating the geometry
243 
244  return true;
245  }
246  // no more provider features
247 
248  close();
249  return false;
250 }
251 
252 
253 
255 {
256  if ( mClosed )
257  return false;
258 
260  {
261  mFetchedFid = false;
262  }
263  else
264  {
267  }
268 
269  return true;
270 }
271 
273 {
274  if ( mClosed )
275  return false;
276 
278 
279  iteratorClosed();
280 
281  mClosed = true;
282  return true;
283 }
284 
285 
286 
287 
289 {
291  {
293 
294  if ( mFetchConsidered.contains( fid ) )
295  // must have changed geometry outside rectangle
296  continue;
297 
299  // skip features which are not accepted by the filter
300  continue;
301 
303 
304  return true;
305  }
306 
308  return false; // no more added features
309 }
310 
311 
313 {
314  f.setFeatureId( src.id() );
315  f.setValid( true );
316  f.setFields( mSource->mFields );
317 
319  {
320  f.setGeometry( new QgsGeometry( *src.constGeometry() ) );
321 
322  // simplify the edited geometry using its simplifier configured
323  if ( mEditGeometrySimplifier )
324  {
325  QgsGeometry* geometry = f.geometry();
326  QGis::GeometryType geometryType = geometry->type();
327  if ( geometryType == QGis::Line || geometryType == QGis::Polygon ) mEditGeometrySimplifier->simplifyGeometry( geometry );
328  }
329  }
330 
331  // TODO[MD]: if subset set just some attributes
332 
333  f.setAttributes( src.attributes() );
334 
335  if ( mHasVirtualAttributes )
337 }
338 
339 
340 
342 {
343  // check if changed geometries are in rectangle
345  {
346  QgsFeatureId fid = mFetchChangedGeomIt.key();
347 
348  if ( mFetchConsidered.contains( fid ) )
349  // skip deleted features
350  continue;
351 
352  mFetchConsidered << fid;
353 
354  if ( !mFetchChangedGeomIt->intersects( mRequest.filterRect() ) )
355  // skip changed geometries not in rectangle and don't check again
356  continue;
357 
359 
360  // return complete feature
362  return true;
363  }
364 
365  return false; // no more changed geometries
366 }
367 
369 {
371  {
372  if ( mFetchConsidered.contains( f.id() ) )
373  // skip deleted features and those already handled by the geometry
374  continue;
375 
376  mFetchConsidered << f.id();
377 
379 
380  if ( mHasVirtualAttributes )
382 
385  {
386  return true;
387  }
388  }
389 
390  return false;
391 }
392 
393 
395 {
396  f.setFeatureId( fid );
397  f.setValid( true );
398  f.setFields( mSource->mFields );
399 
401  {
402  f.setGeometry( geom );
403 
404  // simplify the edited geometry using its simplifier configured
405  if ( mEditGeometrySimplifier )
406  {
407  QgsGeometry* geometry = f.geometry();
408  QGis::GeometryType geometryType = geometry->type();
409  if ( geometryType == QGis::Line || geometryType == QGis::Polygon ) mEditGeometrySimplifier->simplifyGeometry( geometry );
410  }
411  }
412 
413  bool subsetAttrs = ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes );
414  if ( !subsetAttrs || mRequest.subsetOfAttributes().count() > 0 )
415  {
416  // retrieve attributes from provider
417  QgsFeature tmp;
418  //mDataProvider->featureAtId( fid, tmp, false, mFetchProvAttributes );
419  QgsFeatureRequest request;
421  if ( subsetAttrs )
422  {
424  }
426  if ( fi.nextFeature( tmp ) )
427  {
430  f.setAttributes( tmp.attributes() );
431  }
432  }
433 
435 }
436 
437 
438 
440 {
442 
445 }
446 
447 
448 
450 {
452  QgsAttributeList sourceJoinFields; // attributes that also need to be fetched from this layer in order to have joins working
453 
454  mFetchJoinInfo.clear();
455 
456  for ( QgsAttributeList::const_iterator attIt = fetchAttributes.constBegin(); attIt != fetchAttributes.constEnd(); ++attIt )
457  {
458  if ( !mSource->mFields.exists( *attIt ) )
459  continue;
460 
461  if ( mSource->mFields.fieldOrigin( *attIt ) != QgsFields::OriginJoin )
462  continue;
463 
464  int sourceLayerIndex;
465  const QgsVectorJoinInfo* joinInfo = mSource->mJoinBuffer->joinForFieldIndex( *attIt, mSource->mFields, sourceLayerIndex );
466  Q_ASSERT( joinInfo );
467 
468  QgsVectorLayer* joinLayer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( joinInfo->joinLayerId ) );
469  Q_ASSERT( joinLayer );
470 
471  if ( !mFetchJoinInfo.contains( joinInfo ) )
472  {
473  FetchJoinInfo info;
474  info.joinInfo = joinInfo;
475  info.joinLayer = joinLayer;
477 
478  if ( joinInfo->targetFieldName.isEmpty() )
479  info.targetField = joinInfo->targetFieldIndex; //for compatibility with 1.x
480  else
482 
483  if ( joinInfo->joinFieldName.isEmpty() )
484  info.joinField = joinInfo->joinFieldIndex; //for compatibility with 1.x
485  else
486  info.joinField = joinLayer->fields().indexFromName( joinInfo->joinFieldName );
487 
488  // for joined fields, we always need to request the targetField from the provider too
489  if ( !fetchAttributes.contains( info.targetField ) )
490  sourceJoinFields << info.targetField;
491 
492  mFetchJoinInfo.insert( joinInfo, info );
493  }
494 
495  // store field source index - we'll need it when fetching from provider
496  mFetchJoinInfo[ joinInfo ].attributes.push_back( sourceLayerIndex );
497  }
498 
499  // add sourceJoinFields if we're using a subset
502 }
503 
505 {
507 
508  mExpressionContext.reset( new QgsExpressionContext() );
509  mExpressionContext->appendScope( QgsExpressionContextUtils::globalScope() );
510  mExpressionContext->appendScope( QgsExpressionContextUtils::projectScope() );
511  mExpressionContext->setFields( mSource->mFields );
512 
513  for ( int i = 0; i < mSource->mFields.count(); i++ )
514  {
516  {
517  // Only prepare if there is no subset defined or the subset contains this field
520  {
521  int oi = mSource->mFields.fieldOriginIndex( i );
522  QgsExpression* exp = new QgsExpression( exps[oi].expression );
523  exp->prepare( mExpressionContext.data() );
524  mExpressionFieldInfo.insert( i, exp );
525 
527  {
528  QgsAttributeList attrs;
529  Q_FOREACH ( const QString& col, exp->referencedColumns() )
530  {
531  attrs.append( mSource->mFields.fieldNameIndex( col ) );
532  }
533 
535  }
536 
537  if ( exp->needsGeometry() )
538  {
539  mRequest.setFlags( mRequest.flags() & ~QgsFeatureRequest::NoGeometry );
540  }
541  }
542  }
543  }
544 }
545 
547 {
549  for ( ; joinIt != mFetchJoinInfo.constEnd(); ++joinIt )
550  {
551  const FetchJoinInfo& info = joinIt.value();
552  Q_ASSERT( joinIt.key() );
553 
554  QVariant targetFieldValue = f.attribute( info.targetField );
555  if ( !targetFieldValue.isValid() )
556  continue;
557 
558  const QHash< QString, QgsAttributes>& memoryCache = info.joinInfo->cachedAttributes;
559  if ( memoryCache.isEmpty() )
560  info.addJoinedAttributesDirect( f, targetFieldValue );
561  else
562  info.addJoinedAttributesCached( f, targetFieldValue );
563  }
564 }
565 
567 {
568  // make sure we have space for newly added attributes
569  QgsAttributes attr = f.attributes();
570  attr.resize( mSource->mFields.count() ); // Provider attrs count + joined attrs count + expression attrs count
571  f.setAttributes( attr );
572 
573  if ( !mFetchJoinInfo.isEmpty() )
574  addJoinedAttributes( f );
575 
576  if ( !mExpressionFieldInfo.isEmpty() )
577  {
579 
580  for ( ; it != mExpressionFieldInfo.constEnd(); ++it )
581  {
582  QgsExpression* exp = it.value();
583  mExpressionContext->setFeature( f );
584  QVariant val = exp->evaluate( mExpressionContext.data() );
585  mSource->mFields.at( it.key() ).convertCompatible( val );
586  f.setAttribute( it.key(), val );
587  }
588  }
589 }
590 
592 {
593  delete mEditGeometrySimplifier;
594  mEditGeometrySimplifier = NULL;
595 
596  // setup simplification for edited geometries to fetch
598  {
599  mEditGeometrySimplifier = QgsSimplifyMethod::createGeometrySimplifier( simplifyMethod );
600  return mEditGeometrySimplifier != NULL;
601  }
602  return false;
603 }
604 
605 bool QgsVectorLayerFeatureIterator::providerCanSimplify( QgsSimplifyMethod::MethodType methodType ) const
606 {
607  Q_UNUSED( methodType );
608 #if 0
609  // TODO[MD]: after merge
610  QgsVectorDataProvider* provider = L->dataProvider();
611 
612  if ( provider && methodType != QgsSimplifyMethod::NoSimplification )
613  {
614  int capabilities = provider->capabilities();
615 
616  if ( methodType == QgsSimplifyMethod::OptimizeForRendering )
617  {
618  return ( capabilities & QgsVectorDataProvider::SimplifyGeometries );
619  }
620  else if ( methodType == QgsSimplifyMethod::PreserveTopology )
621  {
623  }
624  }
625 #endif
626  return false;
627 }
628 
629 
631 {
633  QHash<QString, QgsAttributes>::const_iterator it = memoryCache.find( joinValue.toString() );
634  if ( it == memoryCache.constEnd() )
635  return; // joined value not found -> leaving the attributes empty (null)
636 
637  int index = indexOffset;
638 
639  const QgsAttributes& featureAttributes = it.value();
640  for ( int i = 0; i < featureAttributes.count(); ++i )
641  {
642  f.setAttribute( index++, featureAttributes.at( i ) );
643  }
644 }
645 
646 
647 
649 {
650  // no memory cache, query the joined values by setting substring
651  QString subsetString = joinLayer->dataProvider()->subsetString(); // provider might already have a subset string
652  QString bkSubsetString = subsetString;
653  if ( !subsetString.isEmpty() )
654  {
655  subsetString.prepend( "(" ).append( ") AND " );
656  }
657 
658  QString joinFieldName;
659  if ( joinInfo->joinFieldName.isEmpty() && joinInfo->joinFieldIndex >= 0 && joinInfo->joinFieldIndex < joinLayer->fields().count() )
660  joinFieldName = joinLayer->fields().field( joinInfo->joinFieldIndex ).name(); // for compatibility with 1.x
661  else
662  joinFieldName = joinInfo->joinFieldName;
663 
664  subsetString.append( QString( "\"%1\"" ).arg( joinFieldName ) );
665 
666  if ( joinValue.isNull() )
667  {
668  subsetString += " IS NULL";
669  }
670  else
671  {
672  QString v = joinValue.toString();
673  switch ( joinValue.type() )
674  {
675  case QVariant::Int:
676  case QVariant::LongLong:
677  case QVariant::Double:
678  break;
679 
680  default:
681  case QVariant::String:
682  v.replace( "'", "''" );
683  v.prepend( "'" ).append( "'" );
684  break;
685  }
686  subsetString += "=" + v;
687  }
688 
689  joinLayer->dataProvider()->setSubsetString( subsetString, false );
690 
691  // maybe user requested just a subset of layer's attributes
692  // so we do not have to cache everything
693  bool hasSubset = joinInfo->joinFieldNamesSubset();
694  QVector<int> subsetIndices;
695  if ( hasSubset )
696  subsetIndices = QgsVectorLayerJoinBuffer::joinSubsetIndices( joinLayer, *joinInfo->joinFieldNamesSubset() );
697 
698  // select (no geometry)
699  QgsFeatureRequest request;
701  request.setSubsetOfAttributes( attributes );
702  QgsFeatureIterator fi = joinLayer->getFeatures( request );
703 
704  // get first feature
705  QgsFeature fet;
706  if ( fi.nextFeature( fet ) )
707  {
708  int index = indexOffset;
709  QgsAttributes attr = fet.attributes();
710  if ( hasSubset )
711  {
712  for ( int i = 0; i < subsetIndices.count(); ++i )
713  f.setAttribute( index++, attr.at( subsetIndices.at( i ) ) );
714  }
715  else
716  {
717  // use all fields except for the one used for join (has same value as exiting field in target layer)
718  for ( int i = 0; i < attr.count(); ++i )
719  {
720  if ( i == joinField )
721  continue;
722 
723  f.setAttribute( index++, attr.at( i ) );
724  }
725  }
726  }
727  else
728  {
729  // no suitable join feature found, keeping empty (null) attributes
730  }
731 
732  joinLayer->dataProvider()->setSubsetString( bkSubsetString, false );
733 }
734 
735 
736 
737 
739 {
740  QgsFeatureId featureId = mRequest.filterFid();
741 
742  // deleted already?
743  if ( mSource->mDeletedFeatureIds.contains( featureId ) )
744  return false;
745 
746  // has changed geometry?
748  {
749  useChangedAttributeFeature( featureId, mSource->mChangedGeometries[featureId], f );
750  return true;
751  }
752 
753  // added features
755  {
756  if ( iter->id() == featureId )
757  {
758  useAddedFeature( *iter, f );
759  return true;
760  }
761  }
762 
763  // regular features
765  if ( fi.nextFeature( f ) )
766  {
767  if ( mSource->mHasEditBuffer )
769 
770  if ( mHasVirtualAttributes )
772 
773  return true;
774  }
775 
776  return false;
777 }
778 
780 {
781  QgsAttributes attrs = f.attributes();
782 
783  // remove all attributes that will disappear - from higher indices to lower
784  for ( int idx = mSource->mDeletedAttributeIds.count() - 1; idx >= 0; --idx )
785  {
786  attrs.remove( mSource->mDeletedAttributeIds[idx] );
787  }
788 
789  // adjust size to accommodate added attributes
790  attrs.resize( attrs.count() + mSource->mAddedAttributes.count() );
791 
792  // update changed attributes
794  {
796  for ( QgsAttributeMap::const_iterator it = map.begin(); it != map.end(); ++it )
797  attrs[it.key()] = it.value();
798  }
799  f.setAttributes( attrs );
800 }
801 
803 {
804  if ( mSource->mChangedGeometries.contains( f.id() ) )
806 }
807 
QgsFeatureId id() const
Get the feature ID for this feature.
Definition: qgsfeature.cpp:53
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:92
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:420
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.
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:185
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
Q_DECL_DEPRECATED QVariant evaluate(const QgsFeature *f)
Evaluate the feature and return the result.
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:422
QgsFields fields() const
Returns the list of fields of this layer.
int fieldNameIndex(const QString &fieldName) const
Look up field's index from name also looks up case-insensitive if there is no match otherwise...
Definition: qgsfield.cpp:382
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's attributes.
Definition: qgsfeature.cpp:97
bool setAttribute(int field, const QVariant &attr)
Set an attribute's value by field index.
Definition: qgsfeature.cpp:194
QMap< int, QgsExpression * > mExpressionFieldInfo
GeometryType
Definition: qgis.h:104
field comes from the underlying data provider of the vector layer (originIndex = index in provider's ...
Definition: qgsfield.h:184
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:176
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'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.
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.cpp:321
void setGeometry(const QgsGeometry &geom)
Set this feature's geometry from another QgsGeometry object.
Definition: qgsfeature.cpp:106
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:83
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:92
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.
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's origin index (its meaning is specific to each type of origin)
Definition: qgsfield.cpp:359
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
int count() const
Return number of items.
Definition: qgsfield.cpp:311
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:331
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:149
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's index from name. Returns -1 on error.
Definition: qgsfield.cpp:364
T * data() const
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:64
QgsVectorLayerFeatureSource(QgsVectorLayer *layer)
bool contains(const T &value) const
const QgsFeatureId & filterFid() const
Get the feature ID that should be fetched.
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.
const Key key(const T &value) const
void setValid(bool validity)
Sets the validity of the feature.
Definition: qgsfeature.cpp:175
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:238
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:417
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:70
FieldOrigin fieldOrigin(int fieldIdx) const
Get field's origin (value from an enumeration)
Definition: qgsfield.cpp:351
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
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: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:187
QString toString() const
QString joinLayerId
Source layer.
QgsAttributeList allAttributesList() const
Utility function to get list of attribute indexes.
Definition: qgsfield.cpp:399
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
Returns the filter expression if set.