QGIS API Documentation  3.20.0-Odense (decaadbb31)
qgscachedfeatureiterator.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscachedfeatureiterator.cpp
3  --------------------------------------
4  Date : 12.2.2013
5  Copyright : (C) 2013 Matthias Kuhn
6  Email : matthias at opengis dot ch
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  ***************************************************************************/
15 
17 #include "qgsvectorlayercache.h"
18 #include "qgsexception.h"
19 #include "qgsvectorlayer.h"
20 
22  : QgsAbstractFeatureIterator( featureRequest )
23  , mVectorLayerCache( vlCache )
24 {
25  if ( mRequest.destinationCrs().isValid() && mRequest.destinationCrs() != mVectorLayerCache->sourceCrs() )
26  {
27  mTransform = QgsCoordinateTransform( mVectorLayerCache->sourceCrs(), mRequest.destinationCrs(), mRequest.transformContext() );
28  }
29  try
30  {
31  mFilterRect = filterRectToSourceCrs( mTransform );
32  }
33  catch ( QgsCsException & )
34  {
35  // can't reproject mFilterRect
36  close();
37  return;
38  }
39  if ( !mFilterRect.isNull() )
40  {
41  // update request to be the unprojected filter rect
42  mRequest.setFilterRect( mFilterRect );
43  }
44 
45  switch ( featureRequest.filterType() )
46  {
48  mFeatureIds = QList< QgsFeatureId >( qgis::setToList( featureRequest.filterFids() ) );
49  break;
50 
52  mFeatureIds = QList< QgsFeatureId >() << featureRequest.filterFid();
53  break;
54 
55  default:
56 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
57  mFeatureIds.clear();
58  mFeatureIds.reserve( static_cast< int >( mVectorLayerCache->mCacheOrderedKeys.size() ) );
59  for ( auto it = mVectorLayerCache->mCacheOrderedKeys.begin(); it != mVectorLayerCache->mCacheOrderedKeys.end(); ++it )
60  mFeatureIds << *it;
61 #else
62  mFeatureIds = QList( mVectorLayerCache->mCacheOrderedKeys.begin(), mVectorLayerCache->mCacheOrderedKeys.end() );
63 #endif
64  break;
65  }
66 
67  mFeatureIdIterator = mFeatureIds.constBegin();
68 
69  if ( mFeatureIdIterator == mFeatureIds.constEnd() )
70  close();
71 }
72 
74 {
75  f.setValid( false );
76 
77  if ( mClosed )
78  return false;
79 
80  while ( mFeatureIdIterator != mFeatureIds.constEnd() )
81  {
82  if ( !mVectorLayerCache->mCache.contains( *mFeatureIdIterator ) )
83  {
84  ++mFeatureIdIterator;
85  continue;
86  }
87 
88  f = QgsFeature( *mVectorLayerCache->mCache[*mFeatureIdIterator]->feature() );
89  ++mFeatureIdIterator;
90  if ( mRequest.acceptFeature( f ) )
91  {
92  f.setValid( true );
93  geometryToDestinationCrs( f, mTransform );
94  return true;
95  }
96  }
97  close();
98  return false;
99 }
100 
102 {
103  mFeatureIdIterator = mFeatureIds.constBegin();
104  return true;
105 }
106 
108 {
109  mClosed = true;
110  mFeatureIds.clear();
111  return true;
112 }
113 
115  : QgsAbstractFeatureIterator( featureRequest )
116  , mVectorLayerCache( vlCache )
117 {
118  if ( mRequest.destinationCrs().isValid() && mRequest.destinationCrs() != mVectorLayerCache->sourceCrs() )
119  {
120  mTransform = QgsCoordinateTransform( mVectorLayerCache->sourceCrs(), mRequest.destinationCrs(), mRequest.transformContext() );
121  }
122  try
123  {
124  mFilterRect = filterRectToSourceCrs( mTransform );
125  }
126  catch ( QgsCsException & )
127  {
128  // can't reproject mFilterRect
129  close();
130  return;
131  }
132  if ( !mFilterRect.isNull() )
133  {
134  // update request to be the unprojected filter rect
135  mRequest.setFilterRect( mFilterRect );
136  }
137 
138  mFeatIt = vlCache->layer()->getFeatures( mRequest );
139 }
140 
142 {
143  if ( mClosed )
144  {
145  f.setValid( false );
146  return false;
147  }
148  if ( mFeatIt.nextFeature( f ) )
149  {
150  // As long as features can be fetched from the provider: Write them to cache
151  mVectorLayerCache->cacheFeature( f );
152  mFids.insert( f.id() );
153  geometryToDestinationCrs( f, mTransform );
154  return true;
155  }
156  else
157  {
158  // Once no more features can be fetched: Inform the cache, that
159  // the request has been completed
160  mVectorLayerCache->requestCompleted( mRequest, mFids );
161  return false;
162  }
163 }
164 
166 {
167  mFids.clear();
168  return mFeatIt.rewind();
169 }
170 
172 {
173  mClosed = true;
174  return mFeatIt.close();
175 }
Internal feature iterator to be implemented within data providers.
void geometryToDestinationCrs(QgsFeature &feature, const QgsCoordinateTransform &transform) const
Transforms feature's geometry according to the specified coordinate transform.
QgsRectangle filterRectToSourceCrs(const QgsCoordinateTransform &transform) const SIP_THROW(QgsCsException)
Returns a rectangle representing the original request's QgsFeatureRequest::filterRect().
QgsFeatureRequest mRequest
A copy of the feature request.
bool mClosed
Sets to true, as soon as the iterator is closed.
bool fetchFeature(QgsFeature &f) override
Implementation for fetching a feature.
QgsCachedFeatureIterator(QgsVectorLayerCache *vlCache, const QgsFeatureRequest &featureRequest)
This constructor creates a feature iterator, that delivers all cached features.
bool close() override
Close this iterator.
bool rewind() override
Rewind to the beginning of the iterator.
bool fetchFeature(QgsFeature &f) override
Implementation for fetching a feature.
bool close() override
Close this iterator.
QgsCachedFeatureWriterIterator(QgsVectorLayerCache *vlCache, const QgsFeatureRequest &featureRequest)
This constructor creates a feature iterator, which queries the backend and caches retrieved features.
bool rewind() override
Rewind to the beginning of the iterator.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
Class for doing transforms between two map coordinate systems.
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:66
bool nextFeature(QgsFeature &f)
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for feature's geometries, or an invalid QgsCoordi...
bool acceptFeature(const QgsFeature &feature)
Check if a feature is accepted by this requests filter.
QgsCoordinateTransformContext transformContext() const
Returns the transform context, for use when a destinationCrs() has been set and reprojection is requi...
FilterType filterType() const
Returns the filter type which is currently set on this request.
const QgsFeatureIds & filterFids() const
Gets feature IDs that should be fetched.
@ FilterFid
Filter using feature ID.
@ FilterFids
Filter using feature IDs.
QgsFeatureId filterFid() const
Gets the feature ID that should be fetched.
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
void setValid(bool validity)
Sets the validity of the feature.
Definition: qgsfeature.cpp:196
Q_GADGET QgsFeatureId id
Definition: qgsfeature.h:64
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
Definition: qgsrectangle.h:479
This class caches features of a given QgsVectorLayer.
void requestCompleted(const QgsFeatureRequest &featureRequest, const QgsFeatureIds &fids)
Gets called, whenever the full list of feature ids for a certain request is known.
QgsVectorLayer * layer()
Returns the layer to which this cache belongs.
QgsCoordinateReferenceSystem sourceCrs() const
Returns the coordinate reference system for features in the cache.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.