QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
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
18#include "qgsexception.h"
19#include "qgsgeometryengine.h"
20#include "qgsvectorlayer.h"
21#include "qgsvectorlayercache.h"
22
24 : QgsAbstractFeatureIterator( featureRequest )
25 , mVectorLayerCache( vlCache )
26{
27 mTransform = mRequest.calculateTransform( mVectorLayerCache->sourceCrs() );
28 try
29 {
30 mFilterRect = filterRectToSourceCrs( mTransform );
31 }
32 catch ( QgsCsException & )
33 {
34 // can't reproject mFilterRect
35 close();
36 return;
37 }
38
39 // prepare spatial filter geometries for optimal speed
40 switch ( mRequest.spatialFilterType() )
41 {
42 case Qgis::SpatialFilterType::NoFilter:
43 case Qgis::SpatialFilterType::BoundingBox:
44 break;
45
46 case Qgis::SpatialFilterType::DistanceWithin:
47 if ( !mRequest.referenceGeometry().isEmpty() )
48 {
49 mDistanceWithinGeom = mRequest.referenceGeometry();
50 mDistanceWithinEngine.reset( QgsGeometry::createGeometryEngine( mDistanceWithinGeom.constGet() ) );
51 mDistanceWithinEngine->prepareGeometry();
52 mDistanceWithin = mRequest.distanceWithin();
53 }
54 break;
55 }
56
57 if ( !mFilterRect.isNull() )
58 {
59 // update request to be the unprojected filter rect
60 mRequest.setFilterRect( mFilterRect );
61 }
62
63 switch ( featureRequest.filterType() )
64 {
65 case Qgis::FeatureRequestFilterType::Fids:
66 {
67 const QgsFeatureIds filterFids = featureRequest.filterFids();
68 mFeatureIds = QList< QgsFeatureId >( filterFids.begin(), filterFids.end() );
69 break;
70 }
71
73 mFeatureIds = QList< QgsFeatureId >() << featureRequest.filterFid();
74 break;
75
78 mFeatureIds = QList( mVectorLayerCache->mCacheOrderedKeys.begin(), mVectorLayerCache->mCacheOrderedKeys.end() );
79 break;
80 }
81
82 mFeatureIdIterator = mFeatureIds.constBegin();
83
84 if ( mFeatureIdIterator == mFeatureIds.constEnd() )
85 close();
86}
87
89
91{
92 f.setValid( false );
93
94 if ( mClosed || !mVectorLayerCache )
95 return false;
96
97 while ( mFeatureIdIterator != mFeatureIds.constEnd() )
98 {
99 if ( !mVectorLayerCache->mCache.contains( *mFeatureIdIterator ) )
100 {
101 ++mFeatureIdIterator;
102 continue;
103 }
104
105 f = QgsFeature( *mVectorLayerCache->mCache[*mFeatureIdIterator]->feature() );
106 ++mFeatureIdIterator;
107 if ( mRequest.acceptFeature( f ) )
108 {
109 f.setValid( true );
110 geometryToDestinationCrs( f, mTransform );
111
112 bool result = true;
113 if ( mDistanceWithinEngine && mDistanceWithinEngine->distance( f.geometry().constGet() ) > mDistanceWithin )
114 {
115 f.setValid( false );
116 result = false;
117 }
118
119 if ( result )
120 return true;
121 }
122 }
123 close();
124 return false;
125}
126
128{
129 mFeatureIdIterator = mFeatureIds.constBegin();
130 return true;
131}
132
134{
135 mClosed = true;
136 mFeatureIds.clear();
137 return true;
138}
139
141 : QgsAbstractFeatureIterator( featureRequest )
142 , mVectorLayerCache( vlCache )
143{
144 mTransform = mRequest.calculateTransform( mVectorLayerCache->sourceCrs() );
145 try
146 {
147 mFilterRect = filterRectToSourceCrs( mTransform );
148 }
149 catch ( QgsCsException & )
150 {
151 // can't reproject mFilterRect
152 close();
153 return;
154 }
155 if ( !mFilterRect.isNull() )
156 {
157 // update request to be the unprojected filter rect
158 mRequest.setFilterRect( mFilterRect );
159 }
160
161 mFeatIt = vlCache->layer()->getFeatures( mRequest );
162}
163
165{
166 if ( mClosed || !mVectorLayerCache )
167 {
168 f.setValid( false );
169 return false;
170 }
171 if ( mFeatIt.nextFeature( f ) )
172 {
173 // As long as features can be fetched from the provider: Write them to cache
174 mVectorLayerCache->cacheFeature( f, ! mRequest.flags().testFlag( Qgis::FeatureRequestFlag::SubsetOfAttributes ) );
175 mFids.insert( f.id() );
176 geometryToDestinationCrs( f, mTransform );
177 return true;
178 }
179 else
180 {
181 // Once no more features can be fetched: Inform the cache, that
182 // the request has been completed
183 mVectorLayerCache->requestCompleted( mRequest, mFids );
184 return false;
185 }
186}
187
189{
190 mFids.clear();
191 return mFeatIt.rewind();
192}
193
195{
196 mClosed = true;
197 return mFeatIt.close();
198}
@ Fid
Filter using feature ID.
Definition qgis.h:2224
@ Expression
Filter using expression.
Definition qgis.h:2225
@ NoFilter
No filter is applied.
Definition qgis.h:2223
@ SubsetOfAttributes
Fetch only a subset of attributes (setSubsetOfAttributes sets this flag).
Definition qgis.h:2197
void geometryToDestinationCrs(QgsFeature &feature, const QgsCoordinateTransform &transform) const
Transforms feature's geometry according to the specified coordinate transform.
QgsFeatureRequest mRequest
A copy of the feature request.
QgsAbstractFeatureIterator(const QgsFeatureRequest &request)
base class constructor - stores the iteration parameters
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.
Custom exception class for Coordinate Reference System related exceptions.
bool rewind()
Resets the iterator to the starting position.
Wraps a request for features to a vector layer (or directly its vector data provider).
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:58
QgsFeatureId id
Definition qgsfeature.h:66
QgsGeometry geometry
Definition qgsfeature.h:69
void setValid(bool validity)
Sets the validity of the feature.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Caches features for a given QgsVectorLayer.
QgsVectorLayer * layer()
Returns the layer to which this cache belongs.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const final
Queries the layer for features specified in request.