QGIS API Documentation 3.32.0-Lima (311a8cb8a6)
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#include "qgsgeometryengine.h"
21
23 : QgsAbstractFeatureIterator( featureRequest )
24 , mVectorLayerCache( vlCache )
25{
26 if ( mRequest.destinationCrs().isValid() && mRequest.destinationCrs() != mVectorLayerCache->sourceCrs() )
27 {
28 mTransform = QgsCoordinateTransform( mVectorLayerCache->sourceCrs(), mRequest.destinationCrs(), mRequest.transformContext() );
29 }
30 try
31 {
32 mFilterRect = filterRectToSourceCrs( mTransform );
33 }
34 catch ( QgsCsException & )
35 {
36 // can't reproject mFilterRect
37 close();
38 return;
39 }
40
41 // prepare spatial filter geometries for optimal speed
42 switch ( mRequest.spatialFilterType() )
43 {
46 break;
47
50 {
51 mDistanceWithinGeom = mRequest.referenceGeometry();
52 mDistanceWithinEngine.reset( QgsGeometry::createGeometryEngine( mDistanceWithinGeom.constGet() ) );
53 mDistanceWithinEngine->prepareGeometry();
54 mDistanceWithin = mRequest.distanceWithin();
55 }
56 break;
57 }
58
59 if ( !mFilterRect.isNull() )
60 {
61 // update request to be the unprojected filter rect
62 mRequest.setFilterRect( mFilterRect );
63 }
64
65 switch ( featureRequest.filterType() )
66 {
68 {
69 const QgsFeatureIds filterFids = featureRequest.filterFids();
70 mFeatureIds = QList< QgsFeatureId >( filterFids.begin(), filterFids.end() );
71 break;
72 }
73
75 mFeatureIds = QList< QgsFeatureId >() << featureRequest.filterFid();
76 break;
77
78 default:
79#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
80 mFeatureIds.clear();
81 mFeatureIds.reserve( static_cast< int >( mVectorLayerCache->mCacheOrderedKeys.size() ) );
82 for ( auto it = mVectorLayerCache->mCacheOrderedKeys.begin(); it != mVectorLayerCache->mCacheOrderedKeys.end(); ++it )
83 mFeatureIds << *it;
84#else
85 mFeatureIds = QList( mVectorLayerCache->mCacheOrderedKeys.begin(), mVectorLayerCache->mCacheOrderedKeys.end() );
86#endif
87 break;
88 }
89
90 mFeatureIdIterator = mFeatureIds.constBegin();
91
92 if ( mFeatureIdIterator == mFeatureIds.constEnd() )
93 close();
94}
95
97
99{
100 f.setValid( false );
101
102 if ( mClosed )
103 return false;
104
105 while ( mFeatureIdIterator != mFeatureIds.constEnd() )
106 {
107 if ( !mVectorLayerCache->mCache.contains( *mFeatureIdIterator ) )
108 {
109 ++mFeatureIdIterator;
110 continue;
111 }
112
113 f = QgsFeature( *mVectorLayerCache->mCache[*mFeatureIdIterator]->feature() );
114 ++mFeatureIdIterator;
115 if ( mRequest.acceptFeature( f ) )
116 {
117 f.setValid( true );
118 geometryToDestinationCrs( f, mTransform );
119
120 bool result = true;
121 if ( mDistanceWithinEngine && mDistanceWithinEngine->distance( f.geometry().constGet() ) > mDistanceWithin )
122 {
123 f.setValid( false );
124 result = false;
125 }
126
127 if ( result )
128 return true;
129 }
130 }
131 close();
132 return false;
133}
134
136{
137 mFeatureIdIterator = mFeatureIds.constBegin();
138 return true;
139}
140
142{
143 mClosed = true;
144 mFeatureIds.clear();
145 return true;
146}
147
149 : QgsAbstractFeatureIterator( featureRequest )
150 , mVectorLayerCache( vlCache )
151{
152 if ( mRequest.destinationCrs().isValid() && mRequest.destinationCrs() != mVectorLayerCache->sourceCrs() )
153 {
154 mTransform = QgsCoordinateTransform( mVectorLayerCache->sourceCrs(), mRequest.destinationCrs(), mRequest.transformContext() );
155 }
156 try
157 {
158 mFilterRect = filterRectToSourceCrs( mTransform );
159 }
160 catch ( QgsCsException & )
161 {
162 // can't reproject mFilterRect
163 close();
164 return;
165 }
166 if ( !mFilterRect.isNull() )
167 {
168 // update request to be the unprojected filter rect
169 mRequest.setFilterRect( mFilterRect );
170 }
171
172 mFeatIt = vlCache->layer()->getFeatures( mRequest );
173}
174
176{
177 if ( mClosed )
178 {
179 f.setValid( false );
180 return false;
181 }
182 if ( mFeatIt.nextFeature( f ) )
183 {
184 // As long as features can be fetched from the provider: Write them to cache
185 mVectorLayerCache->cacheFeature( f, ! mRequest.flags().testFlag( QgsFeatureRequest::Flag::SubsetOfAttributes ) );
186 mFids.insert( f.id() );
187 geometryToDestinationCrs( f, mTransform );
188 return true;
189 }
190 else
191 {
192 // Once no more features can be fetched: Inform the cache, that
193 // the request has been completed
194 mVectorLayerCache->requestCompleted( mRequest, mFids );
195 return false;
196 }
197}
198
200{
201 mFids.clear();
202 return mFeatIt.rewind();
203}
204
206{
207 mClosed = true;
208 return mFeatIt.close();
209}
@ DistanceWithin
Filter by distance to reference geometry.
@ BoundingBox
Filter using a bounding box.
@ NoFilter
No spatial filtering of features.
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.
~QgsCachedFeatureIterator() override
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:67
bool nextFeature(QgsFeature &f)
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsGeometry referenceGeometry() const
Returns the reference geometry used for spatial filtering of features.
Flags flags() const
Returns the flags which affect how features are fetched.
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...
Qgis::SpatialFilterType spatialFilterType() const
Returns the spatial filter type which is currently set on this request.
double distanceWithin() const
Returns the maximum distance from the referenceGeometry() of fetched features, if spatialFilterType()...
FilterType filterType() const
Returns the attribute/ID filter type which is currently set on this request.
@ FilterFid
Filter using feature ID.
@ FilterFids
Filter using feature IDs.
const QgsFeatureIds & filterFids() const
Returns the feature IDs that should be fetched.
QgsFeatureId filterFid() const
Returns 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
QgsGeometry geometry
Definition: qgsfeature.h:67
void setValid(bool validity)
Sets the validity of the feature.
Definition: qgsfeature.cpp:221
Q_GADGET QgsFeatureId id
Definition: qgsfeature.h:64
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine representing the specified geometry.
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
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.
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeatureid.h:37