QGIS API Documentation  2.14.0-Essen
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 #include "qgsdistancearea.h"
27 #include "qgsproject.h"
28 
30  : mCrsId( 0 )
31 {
33  mFields = layer->fields();
34  mJoinBuffer = layer->mJoinBuffer->clone();
35  mExpressionFieldBuffer = new QgsExpressionFieldBuffer( *layer->mExpressionFieldBuffer );
36  mCrsId = layer->crs().srsid();
37 
38  mCanBeSimplified = layer->hasGeometryType() && layer->geometryType() != QGis::Point;
39 
40  mHasEditBuffer = layer->editBuffer();
41  if ( mHasEditBuffer )
42  {
43 #if 0
44  // TODO[MD]: after merge
45  if ( request.filterType() == QgsFeatureRequest::FilterFid )
46  {
47 
48  // only copy relevant parts
49  if ( L->editBuffer()->addedFeatures().contains( request.filterFid() ) )
50  mAddedFeatures.insert( request.filterFid(), L->editBuffer()->addedFeatures()[ request.filterFid()] );
51 
52  if ( L->editBuffer()->changedGeometries().contains( request.filterFid() ) )
53  mChangedGeometries.insert( request.filterFid(), L->editBuffer()->changedGeometries()[ request.filterFid()] );
54 
55  if ( L->editBuffer()->deletedFeatureIds().contains( request.filterFid() ) )
56  mDeletedFeatureIds.insert( request.filterFid() );
57 
58  if ( L->editBuffer()->changedAttributeValues().contains( request.filterFid() ) )
59  mChangedAttributeValues.insert( request.filterFid(), L->editBuffer()->changedAttributeValues()[ request.filterFid()] );
60 
61  if ( L->editBuffer()->changedAttributeValues().contains( request.filterFid() ) )
62  mChangedFeaturesRequest.setFilterFids( QgsFeatureIds() << request.filterFid() );
63  }
64  else
65  {
66 #endif
73 #if 0
74  }
75 #endif
76  }
77 }
78 
80 {
81  delete mJoinBuffer;
84 }
85 
87 {
88  // return feature iterator that does not own this source
89  return QgsFeatureIterator( new QgsVectorLayerFeatureIterator( this, false, request ) );
90 }
91 
92 
95  , mFetchedFid( false )
96  , mEditGeometrySimplifier( nullptr )
97 {
99 
100  // prepare joins: may add more attributes to fetch (in order to allow join)
102  prepareJoins();
103 
105 
106  // by default provider's request is the same
108 
110  {
111  // prepare list of attributes to match provider fields
112  QSet<int> providerSubset;
114  int nPendingFields = mSource->mFields.count();
115  Q_FOREACH ( int attrIndex, subset )
116  {
117  if ( attrIndex < 0 || attrIndex >= nPendingFields ) continue;
118  if ( mSource->mFields.fieldOrigin( attrIndex ) == QgsFields::OriginProvider )
119  providerSubset << mSource->mFields.fieldOriginIndex( attrIndex );
120  }
121 
122  // This is done in order to be prepared to do fallback order bys
123  // and be sure we have the required columns.
124  // TODO:
125  // It would be nicer to first check if we can compile the order by
126  // and only modify the subset if we cannot.
127  if ( !mProviderRequest.orderBy().isEmpty() )
128  {
129  Q_FOREACH ( const QString& attr, mProviderRequest.orderBy().usedAttributes() )
130  {
131  providerSubset << mSource->mFields.fieldNameIndex( attr );
132  }
133  }
134 
135  mProviderRequest.setSubsetOfAttributes( providerSubset.toList() );
136  }
137 
139  {
140  Q_FOREACH ( const QString& field, mProviderRequest.filterExpression()->referencedColumns() )
141  {
142  int idx = source->mFields.fieldNameIndex( field );
143 
144  // If there are fields in the expression which are not of origin provider, the provider will not be able to filter based on them.
145  // In this case we disable the expression filter.
146  if ( source->mFields.fieldOrigin( idx ) != QgsFields::OriginProvider )
147  {
149  }
150  }
151  }
152 
153  if ( mSource->mHasEditBuffer )
154  {
157  }
158 
159  if ( request.filterType() == QgsFeatureRequest::FilterFid )
160  {
161  mFetchedFid = false;
162  }
163  else // no filter or filter by rect
164  {
165  if ( mSource->mHasEditBuffer )
166  {
168  }
169  else
170  {
172  }
173 
175  }
176 
178  {
181  }
182 }
183 
184 
186 {
187  delete mEditGeometrySimplifier;
188  mEditGeometrySimplifier = nullptr;
189 
190  qDeleteAll( mExpressionFieldInfo );
191 
192  close();
193 }
194 
195 
196 
198 {
199  f.setValid( false );
200 
201  if ( mClosed )
202  return false;
203 
205  {
206  if ( mFetchedFid )
207  return false;
208  bool res = nextFeatureFid( f );
209  mFetchedFid = true;
210  return res;
211  }
212 
213  if ( !mRequest.filterRect().isNull() )
214  {
215  if ( fetchNextChangedGeomFeature( f ) )
216  return true;
217 
218  // no more changed geometries
219  }
220 
222  {
224  return true;
225 
226  // no more changed features
227  }
228 
229  while ( fetchNextAddedFeature( f ) )
230  {
231  return true;
232  }
233  // no more added features
234 
235  if ( mProviderIterator.isClosed() )
236  {
239  }
240 
241  while ( mProviderIterator.nextFeature( f ) )
242  {
243  if ( mFetchConsidered.contains( f.id() ) )
244  continue;
245 
246  // TODO[MD]: just one resize of attributes
247  f.setFields( mSource->mFields );
248 
249  // update attributes
250  if ( mSource->mHasEditBuffer )
252 
253  if ( mHasVirtualAttributes )
255 
257  {
258  //filtering by expression, and couldn't do it on the provider side
261  {
262  //feature did not match filter
263  continue;
264  }
265  }
266 
267  // update geometry
268  // TODO[MK]: FilterRect check after updating the geometry
271 
272  return true;
273  }
274  // no more provider features
275 
276  close();
277  return false;
278 }
279 
280 
281 
283 {
284  if ( mClosed )
285  return false;
286 
288  {
289  mFetchedFid = false;
290  }
291  else
292  {
295  }
296 
297  return true;
298 }
299 
301 {
302  if ( mClosed )
303  return false;
304 
306 
307  iteratorClosed();
308 
309  mClosed = true;
310  return true;
311 }
312 
313 
314 
315 
317 {
319  {
321 
322  if ( mFetchConsidered.contains( fid ) )
323  // must have changed geometry outside rectangle
324  continue;
325 
327  // skip features which are not accepted by the filter
328  continue;
329 
331 
332  return true;
333  }
334 
336  return false; // no more added features
337 }
338 
339 
341 {
342  f.setFeatureId( src.id() );
343  f.setValid( true );
344  f.setFields( mSource->mFields );
345 
347  {
348  f.setGeometry( new QgsGeometry( *src.constGeometry() ) );
349 
350  // simplify the edited geometry using its simplifier configured
351  if ( mEditGeometrySimplifier )
352  {
353  QgsGeometry* geometry = f.geometry();
354  QGis::GeometryType geometryType = geometry->type();
355  if ( geometryType == QGis::Line || geometryType == QGis::Polygon ) mEditGeometrySimplifier->simplifyGeometry( geometry );
356  }
357  }
358 
359  // TODO[MD]: if subset set just some attributes
360 
361  f.setAttributes( src.attributes() );
362 
363  if ( mHasVirtualAttributes )
365 }
366 
367 
368 
370 {
371  // check if changed geometries are in rectangle
373  {
374  QgsFeatureId fid = mFetchChangedGeomIt.key();
375 
376  if ( mFetchConsidered.contains( fid ) )
377  // skip deleted features
378  continue;
379 
380  mFetchConsidered << fid;
381 
382  if ( !mFetchChangedGeomIt->intersects( mRequest.filterRect() ) )
383  // skip changed geometries not in rectangle and don't check again
384  continue;
385 
387 
388  // return complete feature
390  return true;
391  }
392 
393  return false; // no more changed geometries
394 }
395 
397 {
399  {
400  if ( mFetchConsidered.contains( f.id() ) )
401  // skip deleted features and those already handled by the geometry
402  continue;
403 
404  mFetchConsidered << f.id();
405 
407 
408  if ( mHasVirtualAttributes )
410 
413  {
414  return true;
415  }
416  }
417 
418  return false;
419 }
420 
421 
423 {
424  f.setFeatureId( fid );
425  f.setValid( true );
426  f.setFields( mSource->mFields );
427 
429  {
430  f.setGeometry( geom );
431 
432  // simplify the edited geometry using its simplifier configured
433  if ( mEditGeometrySimplifier )
434  {
435  QgsGeometry* geometry = f.geometry();
436  QGis::GeometryType geometryType = geometry->type();
437  if ( geometryType == QGis::Line || geometryType == QGis::Polygon ) mEditGeometrySimplifier->simplifyGeometry( geometry );
438  }
439  }
440 
441  bool subsetAttrs = ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes );
442  if ( !subsetAttrs || !mRequest.subsetOfAttributes().isEmpty() )
443  {
444  // retrieve attributes from provider
445  QgsFeature tmp;
446  //mDataProvider->featureAtId( fid, tmp, false, mFetchProvAttributes );
447  QgsFeatureRequest request;
449  if ( subsetAttrs )
450  {
452  }
454  if ( fi.nextFeature( tmp ) )
455  {
458  f.setAttributes( tmp.attributes() );
459  }
460  }
461 
463 }
464 
465 
466 
468 {
470 
473 }
474 
475 
476 
478 {
480  QgsAttributeList sourceJoinFields; // attributes that also need to be fetched from this layer in order to have joins working
481 
482  mFetchJoinInfo.clear();
483 
484  for ( QgsAttributeList::const_iterator attIt = fetchAttributes.constBegin(); attIt != fetchAttributes.constEnd(); ++attIt )
485  {
486  if ( !mSource->mFields.exists( *attIt ) )
487  continue;
488 
489  if ( mSource->mFields.fieldOrigin( *attIt ) != QgsFields::OriginJoin )
490  continue;
491 
492  int sourceLayerIndex;
493  const QgsVectorJoinInfo* joinInfo = mSource->mJoinBuffer->joinForFieldIndex( *attIt, mSource->mFields, sourceLayerIndex );
494  Q_ASSERT( joinInfo );
495 
496  QgsVectorLayer* joinLayer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( joinInfo->joinLayerId ) );
497  Q_ASSERT( joinLayer );
498 
499  if ( !mFetchJoinInfo.contains( joinInfo ) )
500  {
501  FetchJoinInfo info;
502  info.joinInfo = joinInfo;
503  info.joinLayer = joinLayer;
505 
506  if ( joinInfo->targetFieldName.isEmpty() )
507  info.targetField = joinInfo->targetFieldIndex; //for compatibility with 1.x
508  else
510 
511  if ( joinInfo->joinFieldName.isEmpty() )
512  info.joinField = joinInfo->joinFieldIndex; //for compatibility with 1.x
513  else
514  info.joinField = joinLayer->fields().indexFromName( joinInfo->joinFieldName );
515 
516  // for joined fields, we always need to request the targetField from the provider too
517  if ( !fetchAttributes.contains( info.targetField ) )
518  sourceJoinFields << info.targetField;
519 
520  mFetchJoinInfo.insert( joinInfo, info );
521  }
522 
523  // store field source index - we'll need it when fetching from provider
524  mFetchJoinInfo[ joinInfo ].attributes.push_back( sourceLayerIndex );
525  }
526 
527  // add sourceJoinFields if we're using a subset
530 }
531 
533 {
535 
536  mExpressionContext.reset( new QgsExpressionContext() );
537  mExpressionContext->appendScope( QgsExpressionContextUtils::globalScope() );
538  mExpressionContext->appendScope( QgsExpressionContextUtils::projectScope() );
539  mExpressionContext->setFields( mSource->mFields );
540 
541  for ( int i = 0; i < mSource->mFields.count(); i++ )
542  {
544  {
545  // Only prepare if there is no subset defined or the subset contains this field
548  {
549  int oi = mSource->mFields.fieldOriginIndex( i );
550  QgsExpression* exp = new QgsExpression( exps[oi].cachedExpression );
551 
552  QgsDistanceArea da;
553  da.setSourceCrs( mSource->mCrsId );
554  da.setEllipsoidalMode( true );
555  da.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
556  exp->setGeomCalculator( da );
557  exp->setDistanceUnits( QgsProject::instance()->distanceUnits() );
558  exp->setAreaUnits( QgsProject::instance()->areaUnits() );
559 
560  exp->prepare( mExpressionContext.data() );
561  mExpressionFieldInfo.insert( i, exp );
562 
564  {
565  QgsAttributeList attrs;
566  Q_FOREACH ( const QString& col, exp->referencedColumns() )
567  {
568  attrs.append( mSource->mFields.fieldNameIndex( col ) );
569  }
570 
572  }
573 
574  if ( exp->needsGeometry() )
575  {
576  mRequest.setFlags( mRequest.flags() & ~QgsFeatureRequest::NoGeometry );
577  }
578  }
579  }
580  }
581 }
582 
584 {
586  for ( ; joinIt != mFetchJoinInfo.constEnd(); ++joinIt )
587  {
588  const FetchJoinInfo& info = joinIt.value();
589  Q_ASSERT( joinIt.key() );
590 
591  QVariant targetFieldValue = f.attribute( info.targetField );
592  if ( !targetFieldValue.isValid() )
593  continue;
594 
595  const QHash< QString, QgsAttributes>& memoryCache = info.joinInfo->cachedAttributes;
596  if ( memoryCache.isEmpty() )
597  info.addJoinedAttributesDirect( f, targetFieldValue );
598  else
599  info.addJoinedAttributesCached( f, targetFieldValue );
600  }
601 }
602 
604 {
605  // make sure we have space for newly added attributes
606  QgsAttributes attr = f.attributes();
607  attr.resize( mSource->mFields.count() ); // Provider attrs count + joined attrs count + expression attrs count
608  f.setAttributes( attr );
609 
610  if ( !mFetchJoinInfo.isEmpty() )
611  addJoinedAttributes( f );
612 
613  if ( !mExpressionFieldInfo.isEmpty() )
614  {
616 
617  for ( ; it != mExpressionFieldInfo.constEnd(); ++it )
618  {
619  QgsExpression* exp = it.value();
620  mExpressionContext->setFeature( f );
621  QVariant val = exp->evaluate( mExpressionContext.data() );
622  mSource->mFields.at( it.key() ).convertCompatible( val );
623  f.setAttribute( it.key(), val );
624  }
625  }
626 }
627 
629 {
630  delete mEditGeometrySimplifier;
631  mEditGeometrySimplifier = nullptr;
632 
633  // setup simplification for edited geometries to fetch
635  {
636  mEditGeometrySimplifier = QgsSimplifyMethod::createGeometrySimplifier( simplifyMethod );
637  return nullptr != mEditGeometrySimplifier;
638  }
639  return false;
640 }
641 
642 bool QgsVectorLayerFeatureIterator::providerCanSimplify( QgsSimplifyMethod::MethodType methodType ) const
643 {
644  Q_UNUSED( methodType );
645 #if 0
646  // TODO[MD]: after merge
647  QgsVectorDataProvider* provider = L->dataProvider();
648 
649  if ( provider && methodType != QgsSimplifyMethod::NoSimplification )
650  {
651  int capabilities = provider->capabilities();
652 
653  if ( methodType == QgsSimplifyMethod::OptimizeForRendering )
654  {
655  return ( capabilities & QgsVectorDataProvider::SimplifyGeometries );
656  }
657  else if ( methodType == QgsSimplifyMethod::PreserveTopology )
658  {
660  }
661  }
662 #endif
663  return false;
664 }
665 
666 
668 {
669  const QHash<QString, QgsAttributes>& memoryCache = joinInfo->cachedAttributes;
670  QHash<QString, QgsAttributes>::const_iterator it = memoryCache.find( joinValue.toString() );
671  if ( it == memoryCache.constEnd() )
672  return; // joined value not found -> leaving the attributes empty (null)
673 
674  int index = indexOffset;
675 
676  const QgsAttributes& featureAttributes = it.value();
677  for ( int i = 0; i < featureAttributes.count(); ++i )
678  {
679  f.setAttribute( index++, featureAttributes.at( i ) );
680  }
681 }
682 
683 
684 
686 {
687  // no memory cache, query the joined values by setting substring
688  QString subsetString = joinLayer->dataProvider()->subsetString(); // provider might already have a subset string
689  QString bkSubsetString = subsetString;
690  if ( !subsetString.isEmpty() )
691  {
692  subsetString.prepend( '(' ).append( ") AND " );
693  }
694 
695  QString joinFieldName;
696  if ( joinInfo->joinFieldName.isEmpty() && joinInfo->joinFieldIndex >= 0 && joinInfo->joinFieldIndex < joinLayer->fields().count() )
697  joinFieldName = joinLayer->fields().field( joinInfo->joinFieldIndex ).name(); // for compatibility with 1.x
698  else
699  joinFieldName = joinInfo->joinFieldName;
700 
701  subsetString.append( QString( "\"%1\"" ).arg( joinFieldName ) );
702 
703  if ( joinValue.isNull() )
704  {
705  subsetString += " IS NULL";
706  }
707  else
708  {
709  QString v = joinValue.toString();
710  switch ( joinValue.type() )
711  {
712  case QVariant::Int:
713  case QVariant::LongLong:
714  case QVariant::Double:
715  break;
716 
717  default:
718  case QVariant::String:
719  v.replace( '\'', "''" );
720  v.prepend( '\'' ).append( '\'' );
721  break;
722  }
723  subsetString += '=' + v;
724  }
725 
726  joinLayer->dataProvider()->setSubsetString( subsetString, false );
727 
728  // maybe user requested just a subset of layer's attributes
729  // so we do not have to cache everything
730  bool hasSubset = joinInfo->joinFieldNamesSubset();
731  QVector<int> subsetIndices;
732  if ( hasSubset )
733  subsetIndices = QgsVectorLayerJoinBuffer::joinSubsetIndices( joinLayer, *joinInfo->joinFieldNamesSubset() );
734 
735  // select (no geometry)
736  QgsFeatureRequest request;
738  request.setSubsetOfAttributes( attributes );
739  QgsFeatureIterator fi = joinLayer->getFeatures( request );
740 
741  // get first feature
742  QgsFeature fet;
743  if ( fi.nextFeature( fet ) )
744  {
745  int index = indexOffset;
746  QgsAttributes attr = fet.attributes();
747  if ( hasSubset )
748  {
749  for ( int i = 0; i < subsetIndices.count(); ++i )
750  f.setAttribute( index++, attr.at( subsetIndices.at( i ) ) );
751  }
752  else
753  {
754  // use all fields except for the one used for join (has same value as exiting field in target layer)
755  for ( int i = 0; i < attr.count(); ++i )
756  {
757  if ( i == joinField )
758  continue;
759 
760  f.setAttribute( index++, attr.at( i ) );
761  }
762  }
763  }
764  else
765  {
766  // no suitable join feature found, keeping empty (null) attributes
767  }
768 
769  joinLayer->dataProvider()->setSubsetString( bkSubsetString, false );
770 }
771 
772 
773 
774 
776 {
777  QgsFeatureId featureId = mRequest.filterFid();
778 
779  // deleted already?
780  if ( mSource->mDeletedFeatureIds.contains( featureId ) )
781  return false;
782 
783  // has changed geometry?
785  {
786  useChangedAttributeFeature( featureId, mSource->mChangedGeometries[featureId], f );
787  return true;
788  }
789 
790  // added features
792  {
793  if ( iter->id() == featureId )
794  {
795  useAddedFeature( *iter, f );
796  return true;
797  }
798  }
799 
800  // regular features
802  if ( fi.nextFeature( f ) )
803  {
804  if ( mSource->mHasEditBuffer )
806 
807  if ( mHasVirtualAttributes )
809 
810  return true;
811  }
812 
813  return false;
814 }
815 
817 {
818  QgsAttributes attrs = f.attributes();
819 
820  // remove all attributes that will disappear - from higher indices to lower
821  for ( int idx = mSource->mDeletedAttributeIds.count() - 1; idx >= 0; --idx )
822  {
823  attrs.remove( mSource->mDeletedAttributeIds[idx] );
824  }
825 
826  // adjust size to accommodate added attributes
827  attrs.resize( attrs.count() + mSource->mAddedAttributes.count() );
828 
829  // update changed attributes
831  {
833  for ( QgsAttributeMap::const_iterator it = map.begin(); it != map.end(); ++it )
834  attrs[it.key()] = it.value();
835  }
836  f.setAttributes( attrs );
837 }
838 
840 {
841  if ( mSource->mChangedGeometries.contains( f.id() ) )
843 }
844 
845 bool QgsVectorLayerFeatureIterator::prepareOrderBy( const QList<QgsFeatureRequest::OrderByClause>& orderBys )
846 {
847  Q_UNUSED( orderBys );
848  return true;
849 }
850 
QgsFeatureId id() const
Get the feature ID for this feature.
Definition: qgsfeature.cpp:65
void setAreaUnits(QgsUnitTypes::AreaUnit unit)
Sets the desired areal units for calculations involving geomCalculator(), eg "$area".
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:195
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.
long srsid() const
Returns the SrsId, if available.
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:503
QString & prepend(QChar ch)
void setSourceCrs(long srsid)
sets source spatial reference system (by QGIS CRS)
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:194
bool setEllipsoid(const QString &ellipsoid)
Sets ellipsoid by its acronym.
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
const QString GEO_NONE
Constant that holds the string representation for "No ellips/No CRS".
Definition: qgis.cpp:76
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:375
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:419
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:365
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:385
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:424
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
General purpose distance and area calculator.
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
static QgsProject * instance()
access to canonical QgsProject instance
Definition: qgsproject.cpp:381
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
void setDistanceUnits(QGis::UnitType unit)
Sets the desired distance units for calculations involving geomCalculator(), eg "$length" and "$perim...
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:411
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
void setGeomCalculator(const QgsDistanceArea &calc)
Sets the geometry calculator used for distance and area calculations in expressions.
QList< T > toList() const
const QgsCoordinateReferenceSystem & crs() const
Returns layer&#39;s spatial reference system.
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:197
QString toString() const
QString joinLayerId
Source layer.
QgsAttributeList allAttributesList() const
Utility function to get list of attribute indexes.
Definition: qgsfield.cpp:520
MethodType methodType() const
Gets the simplification type.
void setEllipsoidalMode(bool flag)
Sets whether coordinates must be projected to ellipsoid before measuring.
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.