QGIS API Documentation  2.11.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 {
29  mLayer = layer;
31  mFields = layer->fields();
32  mJoinBuffer = layer->mJoinBuffer->clone();
33  mExpressionFieldBuffer = new QgsExpressionFieldBuffer( *layer->mExpressionFieldBuffer );
34 
35  mCanBeSimplified = layer->hasGeometryType() && layer->geometryType() != QGis::Point;
36 
37  mHasEditBuffer = layer->editBuffer();
38  if ( mHasEditBuffer )
39  {
40 #if 0
41  // TODO[MD]: after merge
42  if ( request.filterType() == QgsFeatureRequest::FilterFid )
43  {
44 
45  // only copy relevant parts
46  if ( L->editBuffer()->addedFeatures().contains( request.filterFid() ) )
47  mAddedFeatures.insert( request.filterFid(), L->editBuffer()->addedFeatures()[ request.filterFid()] );
48 
49  if ( L->editBuffer()->changedGeometries().contains( request.filterFid() ) )
50  mChangedGeometries.insert( request.filterFid(), L->editBuffer()->changedGeometries()[ request.filterFid()] );
51 
52  if ( L->editBuffer()->deletedFeatureIds().contains( request.filterFid() ) )
53  mDeletedFeatureIds.insert( request.filterFid() );
54 
55  if ( L->editBuffer()->changedAttributeValues().contains( request.filterFid() ) )
56  mChangedAttributeValues.insert( request.filterFid(), L->editBuffer()->changedAttributeValues()[ request.filterFid()] );
57 
58  if ( L->editBuffer()->changedAttributeValues().contains( request.filterFid() ) )
59  mChangedFeaturesRequest.setFilterFids( QgsFeatureIds() << request.filterFid() );
60  }
61  else
62  {
63 #endif
70 #if 0
71  }
72 #endif
73  }
74 }
75 
77 {
78  delete mJoinBuffer;
81 }
82 
84 {
85  // return feature iterator that does not own this source
86  return QgsFeatureIterator( new QgsVectorLayerFeatureIterator( this, false, request ) );
87 }
88 
89 
92  , mFetchedFid( false )
93  , mEditGeometrySimplifier( 0 )
94 {
96 
97  // prepare joins: may add more attributes to fetch (in order to allow join)
99  prepareJoins();
100 
102 
103  // by default provider's request is the same
105 
107  {
108  // prepare list of attributes to match provider fields
109  QgsAttributeList providerSubset;
111  int nPendingFields = mSource->mFields.count();
112  for ( int i = 0; i < subset.count(); ++i )
113  {
114  int attrIndex = subset[i];
115  if ( attrIndex < 0 || attrIndex >= nPendingFields ) continue;
116  if ( mSource->mFields.fieldOrigin( attrIndex ) == QgsFields::OriginProvider )
117  providerSubset << mSource->mFields.fieldOriginIndex( attrIndex );
118  }
119  mProviderRequest.setSubsetOfAttributes( providerSubset );
120  }
121 
123  {
124  Q_FOREACH ( const QString& field, mProviderRequest.filterExpression()->referencedColumns() )
125  {
126  int idx = source->mFields.fieldNameIndex( field );
127 
128  // If there are fields in the expression which are not of origin provider, the provider will not be able to filter based on them.
129  // In this case we disable the expression filter.
130  if ( source->mFields.fieldOrigin( idx ) != QgsFields::OriginProvider )
131  {
133  }
134  }
135  }
136 
137  if ( mSource->mHasEditBuffer )
138  {
141  }
142 
143  if ( request.filterType() == QgsFeatureRequest::FilterFid )
144  {
145  mFetchedFid = false;
146  }
147  else // no filter or filter by rect
148  {
149  if ( mSource->mHasEditBuffer )
150  {
152  }
153  else
154  {
156  }
157 
159  }
160 
162  {
165  }
166 }
167 
168 
170 {
171  delete mEditGeometrySimplifier;
172  mEditGeometrySimplifier = NULL;
173 
174  qDeleteAll( mExpressionFieldInfo.values() );
175 
176  close();
177 }
178 
179 
180 
182 {
183  f.setValid( false );
184 
185  if ( mClosed )
186  return false;
187 
189  {
190  if ( mFetchedFid )
191  return false;
192  bool res = nextFeatureFid( f );
193  mFetchedFid = true;
194  return res;
195  }
196 
197  if ( !mRequest.filterRect().isNull() )
198  {
199  if ( fetchNextChangedGeomFeature( f ) )
200  return true;
201 
202  // no more changed geometries
203  }
204 
206  {
208  return true;
209 
210  // no more changed features
211  }
212 
213  while ( fetchNextAddedFeature( f ) )
214  {
215  return true;
216  }
217  // no more added features
218 
219  if ( mProviderIterator.isClosed() )
220  {
223  }
224 
225  while ( mProviderIterator.nextFeature( f ) )
226  {
227  if ( mFetchConsidered.contains( f.id() ) )
228  continue;
229 
230  // TODO[MD]: just one resize of attributes
231  f.setFields( mSource->mFields );
232 
233  // update attributes
234  if ( mSource->mHasEditBuffer )
236 
237  if ( mHasVirtualAttributes )
239 
240  // update geometry
241  // TODO[MK]: FilterRect check after updating the geometry
244 
245  return true;
246  }
247  // no more provider features
248 
249  close();
250  return false;
251 }
252 
253 
254 
256 {
257  if ( mClosed )
258  return false;
259 
261  {
262  mFetchedFid = false;
263  }
264  else
265  {
268  }
269 
270  return true;
271 }
272 
274 {
275  if ( mClosed )
276  return false;
277 
279 
280  iteratorClosed();
281 
282  mClosed = true;
283  return true;
284 }
285 
286 
287 
288 
290 {
292  {
294 
295  if ( mFetchConsidered.contains( fid ) )
296  // must have changed geometry outside rectangle
297  continue;
298 
300  // skip features which are not accepted by the filter
301  continue;
302 
304 
305  return true;
306  }
307 
309  return false; // no more added features
310 }
311 
312 
314 {
315  f.setFeatureId( src.id() );
316  f.setValid( true );
317  f.setFields( mSource->mFields );
318 
320  {
321  f.setGeometry( new QgsGeometry( *src.constGeometry() ) );
322 
323  // simplify the edited geometry using its simplifier configured
324  if ( mEditGeometrySimplifier )
325  {
326  QgsGeometry* geometry = f.geometry();
327  QGis::GeometryType geometryType = geometry->type();
328  if ( geometryType == QGis::Line || geometryType == QGis::Polygon ) mEditGeometrySimplifier->simplifyGeometry( geometry );
329  }
330  }
331 
332  // TODO[MD]: if subset set just some attributes
333 
334  f.setAttributes( src.attributes() );
335 
336  if ( mHasVirtualAttributes )
338 }
339 
340 
341 
343 {
344  // check if changed geometries are in rectangle
346  {
347  QgsFeatureId fid = mFetchChangedGeomIt.key();
348 
349  if ( mFetchConsidered.contains( fid ) )
350  // skip deleted features
351  continue;
352 
353  mFetchConsidered << fid;
354 
355  if ( !mFetchChangedGeomIt->intersects( mRequest.filterRect() ) )
356  // skip changed geometries not in rectangle and don't check again
357  continue;
358 
360 
361  // return complete feature
363  return true;
364  }
365 
366  return false; // no more changed geometries
367 }
368 
370 {
372  {
373  if ( mFetchConsidered.contains( f.id() ) )
374  // skip deleted features and those already handled by the geometry
375  continue;
376 
377  mFetchConsidered << f.id();
378 
380 
381  if ( mHasVirtualAttributes )
383 
386  {
387  return true;
388  }
389  }
390 
391  return false;
392 }
393 
394 
396 {
397  f.setFeatureId( fid );
398  f.setValid( true );
399  f.setFields( mSource->mFields );
400 
402  {
403  f.setGeometry( geom );
404 
405  // simplify the edited geometry using its simplifier configured
406  if ( mEditGeometrySimplifier )
407  {
408  QgsGeometry* geometry = f.geometry();
409  QGis::GeometryType geometryType = geometry->type();
410  if ( geometryType == QGis::Line || geometryType == QGis::Polygon ) mEditGeometrySimplifier->simplifyGeometry( geometry );
411  }
412  }
413 
414  bool subsetAttrs = ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes );
415  if ( !subsetAttrs || ( subsetAttrs && mRequest.subsetOfAttributes().count() > 0 ) )
416  {
417  // retrieve attributes from provider
418  QgsFeature tmp;
419  //mDataProvider->featureAtId( fid, tmp, false, mFetchProvAttributes );
420  QgsFeatureRequest request;
422  if ( subsetAttrs )
423  {
425  }
427  if ( fi.nextFeature( tmp ) )
428  {
431  f.setAttributes( tmp.attributes() );
432  }
433  }
434 
436 }
437 
438 
439 
441 {
443 
446 }
447 
448 
449 
451 {
453  QgsAttributeList sourceJoinFields; // attributes that also need to be fetched from this layer in order to have joins working
454 
455  mFetchJoinInfo.clear();
456 
457  for ( QgsAttributeList::const_iterator attIt = fetchAttributes.constBegin(); attIt != fetchAttributes.constEnd(); ++attIt )
458  {
459  if ( !mSource->mFields.exists( *attIt ) )
460  continue;
461 
462  if ( mSource->mFields.fieldOrigin( *attIt ) != QgsFields::OriginJoin )
463  continue;
464 
465  int sourceLayerIndex;
466  const QgsVectorJoinInfo* joinInfo = mSource->mJoinBuffer->joinForFieldIndex( *attIt, mSource->mFields, sourceLayerIndex );
467  Q_ASSERT( joinInfo );
468 
469  QgsVectorLayer* joinLayer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( joinInfo->joinLayerId ) );
470  Q_ASSERT( joinLayer );
471 
472  if ( !mFetchJoinInfo.contains( joinInfo ) )
473  {
474  FetchJoinInfo info;
475  info.joinInfo = joinInfo;
476  info.joinLayer = joinLayer;
478 
479  if ( joinInfo->targetFieldName.isEmpty() )
480  info.targetField = joinInfo->targetFieldIndex; //for compatibility with 1.x
481  else
483 
484  if ( joinInfo->joinFieldName.isEmpty() )
485  info.joinField = joinInfo->joinFieldIndex; //for compatibility with 1.x
486  else
487  info.joinField = joinLayer->fields().indexFromName( joinInfo->joinFieldName );
488 
489  // for joined fields, we always need to request the targetField from the provider too
490  if ( !fetchAttributes.contains( info.targetField ) )
491  sourceJoinFields << info.targetField;
492 
493  mFetchJoinInfo.insert( joinInfo, info );
494  }
495 
496  // store field source index - we'll need it when fetching from provider
497  mFetchJoinInfo[ joinInfo ].attributes.push_back( sourceLayerIndex );
498  }
499 
500  // add sourceJoinFields if we're using a subset
503 }
504 
506 {
508 
509  mExpressionContext.reset( new QgsExpressionContext() );
510  mExpressionContext->appendScope( QgsExpressionContextUtils::globalScope() );
511  mExpressionContext->appendScope( QgsExpressionContextUtils::projectScope() );
512  mExpressionContext->setFields( mSource->mFields );
513 
514  for ( int i = 0; i < mSource->mFields.count(); i++ )
515  {
517  {
518  // Only prepare if there is no subset defined or the subset contains this field
521  {
522  int oi = mSource->mFields.fieldOriginIndex( i );
523  QgsExpression* exp = new QgsExpression( exps[oi].expression );
524  exp->prepare( mExpressionContext.data() );
525  mExpressionFieldInfo.insert( i, exp );
526 
528  {
529  QgsAttributeList attrs;
530  Q_FOREACH ( const QString& col, exp->referencedColumns() )
531  {
532  attrs.append( mSource->mFields.fieldNameIndex( col ) );
533  }
534 
536  }
537 
538  if ( exp->needsGeometry() )
539  {
540  mRequest.setFlags( mRequest.flags() & ~QgsFeatureRequest::NoGeometry );
541  }
542  }
543  }
544  }
545 }
546 
548 {
550  for ( ; joinIt != mFetchJoinInfo.constEnd(); ++joinIt )
551  {
552  const FetchJoinInfo& info = joinIt.value();
553  Q_ASSERT( joinIt.key() );
554 
555  QVariant targetFieldValue = f.attribute( info.targetField );
556  if ( !targetFieldValue.isValid() )
557  continue;
558 
559  const QHash< QString, QgsAttributes>& memoryCache = info.joinInfo->cachedAttributes;
560  if ( memoryCache.isEmpty() )
561  info.addJoinedAttributesDirect( f, targetFieldValue );
562  else
563  info.addJoinedAttributesCached( f, targetFieldValue );
564  }
565 }
566 
568 {
569  // make sure we have space for newly added attributes
570  QgsAttributes attr = f.attributes();
571  attr.resize( mSource->mFields.count() ); // Provider attrs count + joined attrs count + expression attrs count
572  f.setAttributes( attr );
573 
574  if ( !mFetchJoinInfo.isEmpty() )
575  addJoinedAttributes( f );
576 
577  if ( !mExpressionFieldInfo.isEmpty() )
578  {
580 
581  for ( ; it != mExpressionFieldInfo.constEnd(); ++it )
582  {
583  QgsExpression* exp = it.value();
584  mExpressionContext->setFeature( f );
585  QVariant val = exp->evaluate( mExpressionContext.data() );
586  mSource->mFields.at( it.key() ).convertCompatible( val );;
587  f.setAttribute( it.key(), val );
588  }
589  }
590 }
591 
593 {
594  delete mEditGeometrySimplifier;
595  mEditGeometrySimplifier = NULL;
596 
597  // setup simplification for edited geometries to fetch
599  {
600  mEditGeometrySimplifier = QgsSimplifyMethod::createGeometrySimplifier( simplifyMethod );
601  return mEditGeometrySimplifier != NULL;
602  }
603  return false;
604 }
605 
606 bool QgsVectorLayerFeatureIterator::providerCanSimplify( QgsSimplifyMethod::MethodType methodType ) const
607 {
608  Q_UNUSED( methodType );
609 #if 0
610  // TODO[MD]: after merge
611  QgsVectorDataProvider* provider = L->dataProvider();
612 
613  if ( provider && methodType != QgsSimplifyMethod::NoSimplification )
614  {
615  int capabilities = provider->capabilities();
616 
617  if ( methodType == QgsSimplifyMethod::OptimizeForRendering )
618  {
619  return ( capabilities & QgsVectorDataProvider::SimplifyGeometries );
620  }
621  else if ( methodType == QgsSimplifyMethod::PreserveTopology )
622  {
624  }
625  }
626 #endif
627  return false;
628 }
629 
630 
632 {
634  QHash<QString, QgsAttributes>::const_iterator it = memoryCache.find( joinValue.toString() );
635  if ( it == memoryCache.constEnd() )
636  return; // joined value not found -> leaving the attributes empty (null)
637 
638  int index = indexOffset;
639 
640  const QgsAttributes& featureAttributes = it.value();
641  for ( int i = 0; i < featureAttributes.count(); ++i )
642  {
643  f.setAttribute( index++, featureAttributes[i] );
644  }
645 }
646 
647 
648 
650 {
651  // no memory cache, query the joined values by setting substring
652  QString subsetString = joinLayer->dataProvider()->subsetString(); // provider might already have a subset string
653  QString bkSubsetString = subsetString;
654  if ( !subsetString.isEmpty() )
655  {
656  subsetString.prepend( "(" ).append( ") AND " );
657  }
658 
659  QString joinFieldName;
660  if ( joinInfo->joinFieldName.isEmpty() && joinInfo->joinFieldIndex >= 0 && joinInfo->joinFieldIndex < joinLayer->fields().count() )
661  joinFieldName = joinLayer->fields().field( joinInfo->joinFieldIndex ).name(); // for compatibility with 1.x
662  else
663  joinFieldName = joinInfo->joinFieldName;
664 
665  subsetString.append( QString( "\"%1\"" ).arg( joinFieldName ) );
666 
667  if ( joinValue.isNull() )
668  {
669  subsetString += " IS NULL";
670  }
671  else
672  {
673  QString v = joinValue.toString();
674  switch ( joinValue.type() )
675  {
676  case QVariant::Int:
677  case QVariant::LongLong:
678  case QVariant::Double:
679  break;
680 
681  default:
682  case QVariant::String:
683  v.replace( "'", "''" );
684  v.prepend( "'" ).append( "'" );
685  break;
686  }
687  subsetString += "=" + v;
688  }
689 
690  joinLayer->dataProvider()->setSubsetString( subsetString, false );
691 
692  // maybe user requested just a subset of layer's attributes
693  // so we do not have to cache everything
694  bool hasSubset = joinInfo->joinFieldNamesSubset();
695  QVector<int> subsetIndices;
696  if ( hasSubset )
697  subsetIndices = QgsVectorLayerJoinBuffer::joinSubsetIndices( joinLayer, *joinInfo->joinFieldNamesSubset() );
698 
699  // select (no geometry)
700  QgsFeatureRequest request;
702  request.setSubsetOfAttributes( attributes );
703  QgsFeatureIterator fi = joinLayer->getFeatures( request );
704 
705  // get first feature
706  QgsFeature fet;
707  if ( fi.nextFeature( fet ) )
708  {
709  int index = indexOffset;
710  QgsAttributes attr = fet.attributes();
711  if ( hasSubset )
712  {
713  for ( int i = 0; i < subsetIndices.count(); ++i )
714  f.setAttribute( index++, attr[ subsetIndices[i] ] );
715  }
716  else
717  {
718  // use all fields except for the one used for join (has same value as exiting field in target layer)
719  for ( int i = 0; i < attr.count(); ++i )
720  {
721  if ( i == joinField )
722  continue;
723 
724  f.setAttribute( index++, attr[i] );
725  }
726  }
727  }
728  else
729  {
730  // no suitable join feature found, keeping empty (null) attributes
731  }
732 
733  joinLayer->dataProvider()->setSubsetString( bkSubsetString, false );
734 }
735 
736 
737 
738 
740 {
741  QgsFeatureId featureId = mRequest.filterFid();
742 
743  // deleted already?
744  if ( mSource->mDeletedFeatureIds.contains( featureId ) )
745  return false;
746 
747  // has changed geometry?
749  {
750  useChangedAttributeFeature( featureId, mSource->mChangedGeometries[featureId], f );
751  return true;
752  }
753 
754  // added features
756  {
757  if ( iter->id() == featureId )
758  {
759  useAddedFeature( *iter, f );
760  return true;
761  }
762  }
763 
764  // regular features
766  if ( fi.nextFeature( f ) )
767  {
768  if ( mSource->mHasEditBuffer )
770 
771  if ( mHasVirtualAttributes )
773 
774  return true;
775  }
776 
777  return false;
778 }
779 
781 {
782  QgsAttributes attrs = f.attributes();
783 
784  // remove all attributes that will disappear - from higher indices to lower
785  for ( int idx = mSource->mDeletedAttributeIds.count() - 1; idx >= 0; --idx )
786  {
787  attrs.remove( mSource->mDeletedAttributeIds[idx] );
788  }
789 
790  // adjust size to accommodate added attributes
791  attrs.resize( attrs.count() + mSource->mAddedAttributes.count() );
792 
793  // update changed attributes
795  {
797  for ( QgsAttributeMap::const_iterator it = map.begin(); it != map.end(); ++it )
798  attrs[it.key()] = it.value();
799  }
800  f.setAttributes( attrs );
801 }
802 
804 {
805  if ( mSource->mChangedGeometries.contains( f.id() ) )
807 }
808 
QgsFeatureId id() const
Get the feature ID for this feature.
Definition: qgsfeature.cpp:51
const QgsGeometryMap & changedGeometries()
Changed geometries which are not commited.
QgsAbstractFeatureSource * mProviderFeatureSource
Class for parsing and evaluation of expressions (formerly called "search strings").
Definition: qgsexpression.h:88
Wrapper for iterator of features from vector data provider or vector layer.
void addJoinedAttributesDirect(QgsFeature &f, const QVariant &joinValue) const
QMap< QgsFeatureId, QgsGeometry > QgsGeometryMap
Definition: qgsfeature.h:406
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.
QList< T > values() const
QgsFeatureMap::ConstIterator mFetchAddedFeaturesIt
QgsGeometryMap::ConstIterator mFetchChangedGeomIt
const QgsRectangle & filterRect() const
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:408
QgsFields fields() const
Returns the list of fields of this layer.
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:356
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:75
const QgsAttributeList & subsetOfAttributes() const
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
Definition: qgsfeature.cpp:95
bool setAttribute(int field, const QVariant &attr)
Set an attribute's value by field index.
Definition: qgsfeature.cpp:192
QMap< int, QgsExpression * > mExpressionFieldInfo
GeometryType
Definition: qgis.h:155
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:162
QgsVectorLayer * joinLayer
resolved pointer to the joined layer
bool isClosed() const
find out whether the iterator is still valid or closed already
QMap< const QgsVectorJoinInfo *, FetchJoinInfo > mFetchJoinInfo
Information about joins used in the current select() statement.
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:295
void setGeometry(const QgsGeometry &geom)
Set this feature's geometry from another QgsGeometry object.
Definition: qgsfeature.cpp:104
QgsVectorLayerEditBuffer * editBuffer()
Buffer with uncommitted editing operations. Only valid after editing has been turned on...
int count(const T &value) const
void iteratorClosed()
to be called by from subclass in close()
void append(const T &value)
void useAddedFeature(const QgsFeature &src, QgsFeature &f)
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context...
QgsFeatureRequest & setFilterFids(QgsFeatureIds fids)
Set feature ID that should be fetched.
void resize(int size)
const_iterator constEnd() const
void setFeatureId(QgsFeatureId id)
Sets the feature ID for this feature.
Definition: qgsfeature.cpp:81
bool isNull() const
const Key & key() const
const QgsVectorJoinInfo * joinInfo
cannonical source of information about the join
QgsAttributes attributes() const
Returns the feature's attributes.
Definition: qgsfeature.cpp:90
virtual int capabilities() const
Returns a bitmask containing the supported capabilities Note, some capabilities may change depending ...
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:333
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:285
No simplification is applied.
QGis::GeometryType geometryType() const
Returns point, line or polygon.
FilterType filterType() const
iterator end()
Fetch only a subset of attributes (setSubsetOfAttributes sets this flag)
QgsExpressionFieldBuffer * mExpressionFieldBuffer
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfield.cpp:305
iterator begin()
Q_DECL_DEPRECATED void setFields(const QgsFields *fields, bool initAttributes=false)
Assign a field map with the feature to allow attribute access by attribute name.
Definition: qgsfeature.cpp:147
const QList< QgsField > & addedAttributes()
Added attributes fields which are not commited.
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:338
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:62
QgsVectorLayerFeatureSource(QgsVectorLayer *layer)
bool contains(const T &value) const
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.
const Key key(const T &value) const
void setValid(bool validity)
Sets the validity of the feature.
Definition: qgsfeature.cpp:173
QMap< QgsFeatureId, QgsFeature > QgsFeatureMap
QString & replace(int position, int n, QChar after)
QgsFeatureRequest mRequest
A copy of the feature request.
bool hasGeometryType() const
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
int targetField
index of field (of this layer) that drives the join
Buffers information about expression fields for a vector layer.
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call.
QHash< QString, QgsAttributes > cachedAttributes
Cache for joined attributes to provide fast lookup (size is 0 if no memory caching) ...
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:236
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request) override
QMap< QgsFeatureId, QgsAttributeMap > QgsChangedAttributesMap
Definition: qgsfeature.h:403
bool isEmpty() const
virtual bool rewind() override
reset the iterator to the starting position
virtual bool close() override
end of iterating: free the resources / lock
static QVector< int > joinSubsetIndices(QgsVectorLayer *joinLayer, const QStringList &joinFieldsSubset)
Return a vector of indices for use in join based on field names from the layer.
int count(const T &value) const
const QgsGeometry * constGeometry() const
Gets a const pointer to the geometry object associated with this feature.
Definition: qgsfeature.cpp:68
FieldOrigin fieldOrigin(int fieldIdx) const
Get field's origin (value from an enumeration)
Definition: qgsfield.cpp:325
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
QgsMapLayer * mapLayer(QString theLayerId)
Retrieve a pointer to a loaded layer by id.
This class contains information about how to simplify geometries fetched from a QgsFeatureIterator.
iterator insert(const Key &key, const T &value)
void addJoinedAttributesCached(QgsFeature &f, const QVariant &joinValue) const
bool isEmpty() const
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
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
QgsFeatureRequest & setFlags(Flags flags)
Set flags that affect how features will be fetched.
QString toString() const
QString joinLayerId
Source layer.
QgsAttributeList allAttributesList() const
Utility function to get list of attribute indexes.
Definition: qgsfield.cpp:368
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.