QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
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  mFeatureIds = QList< QgsFeatureId >( qgis::setToList( featureRequest.filterFids() ) );
69  break;
70 
72  mFeatureIds = QList< QgsFeatureId >() << featureRequest.filterFid();
73  break;
74 
75  default:
76 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
77  mFeatureIds.clear();
78  mFeatureIds.reserve( static_cast< int >( mVectorLayerCache->mCacheOrderedKeys.size() ) );
79  for ( auto it = mVectorLayerCache->mCacheOrderedKeys.begin(); it != mVectorLayerCache->mCacheOrderedKeys.end(); ++it )
80  mFeatureIds << *it;
81 #else
82  mFeatureIds = QList( mVectorLayerCache->mCacheOrderedKeys.begin(), mVectorLayerCache->mCacheOrderedKeys.end() );
83 #endif
84  break;
85  }
86 
87  mFeatureIdIterator = mFeatureIds.constBegin();
88 
89  if ( mFeatureIdIterator == mFeatureIds.constEnd() )
90  close();
91 }
92 
94 
96 {
97  f.setValid( false );
98 
99  if ( mClosed )
100  return false;
101 
102  while ( mFeatureIdIterator != mFeatureIds.constEnd() )
103  {
104  if ( !mVectorLayerCache->mCache.contains( *mFeatureIdIterator ) )
105  {
106  ++mFeatureIdIterator;
107  continue;
108  }
109 
110  f = QgsFeature( *mVectorLayerCache->mCache[*mFeatureIdIterator]->feature() );
111  ++mFeatureIdIterator;
112  if ( mRequest.acceptFeature( f ) )
113  {
114  f.setValid( true );
115  geometryToDestinationCrs( f, mTransform );
116 
117  bool result = true;
118  if ( mDistanceWithinEngine && mDistanceWithinEngine->distance( f.geometry().constGet() ) > mDistanceWithin )
119  {
120  f.setValid( false );
121  result = false;
122  }
123 
124  if ( result )
125  return true;
126  }
127  }
128  close();
129  return false;
130 }
131 
133 {
134  mFeatureIdIterator = mFeatureIds.constBegin();
135  return true;
136 }
137 
139 {
140  mClosed = true;
141  mFeatureIds.clear();
142  return true;
143 }
144 
146  : QgsAbstractFeatureIterator( featureRequest )
147  , mVectorLayerCache( vlCache )
148 {
149  if ( mRequest.destinationCrs().isValid() && mRequest.destinationCrs() != mVectorLayerCache->sourceCrs() )
150  {
151  mTransform = QgsCoordinateTransform( mVectorLayerCache->sourceCrs(), mRequest.destinationCrs(), mRequest.transformContext() );
152  }
153  try
154  {
155  mFilterRect = filterRectToSourceCrs( mTransform );
156  }
157  catch ( QgsCsException & )
158  {
159  // can't reproject mFilterRect
160  close();
161  return;
162  }
163  if ( !mFilterRect.isNull() )
164  {
165  // update request to be the unprojected filter rect
166  mRequest.setFilterRect( mFilterRect );
167  }
168 
169  mFeatIt = vlCache->layer()->getFeatures( mRequest );
170 }
171 
173 {
174  if ( mClosed )
175  {
176  f.setValid( false );
177  return false;
178  }
179  if ( mFeatIt.nextFeature( f ) )
180  {
181  // As long as features can be fetched from the provider: Write them to cache
182  mVectorLayerCache->cacheFeature( f );
183  mFids.insert( f.id() );
184  geometryToDestinationCrs( f, mTransform );
185  return true;
186  }
187  else
188  {
189  // Once no more features can be fetched: Inform the cache, that
190  // the request has been completed
191  mVectorLayerCache->requestCompleted( mRequest, mFids );
192  return false;
193  }
194 }
195 
197 {
198  mFids.clear();
199  return mFeatIt.rewind();
200 }
201 
203 {
204  mClosed = true;
205  return mFeatIt.close();
206 }
QgsVectorLayer::getFeatures
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
Definition: qgsvectorlayer.cpp:1052
QgsFeatureRequest::FilterFid
@ FilterFid
Filter using feature ID.
Definition: qgsfeaturerequest.h:116
QgsCachedFeatureIterator::~QgsCachedFeatureIterator
~QgsCachedFeatureIterator() override
qgsvectorlayercache.h
QgsFeatureRequest::filterFids
const QgsFeatureIds & filterFids() const
Returns the feature IDs that should be fetched.
Definition: qgsfeaturerequest.h:492
QgsVectorLayerCache
This class caches features of a given QgsVectorLayer.
Definition: qgsvectorlayercache.h:46
Qgis::SpatialFilterType::NoFilter
@ NoFilter
No spatial filtering of features.
QgsFeatureRequest::transformContext
QgsCoordinateTransformContext transformContext() const
Returns the transform context, for use when a destinationCrs() has been set and reprojection is requi...
Definition: qgsfeaturerequest.cpp:296
QgsFeatureRequest::acceptFeature
bool acceptFeature(const QgsFeature &feature)
Check if a feature is accepted by this requests filter.
Definition: qgsfeaturerequest.cpp:314
QgsVectorLayerCache::requestCompleted
void requestCompleted(const QgsFeatureRequest &featureRequest, const QgsFeatureIds &fids)
Gets called, whenever the full list of feature ids for a certain request is known.
Definition: qgsvectorlayercache.cpp:217
QgsFeatureRequest::filterFid
QgsFeatureId filterFid() const
Returns the feature ID that should be fetched.
Definition: qgsfeaturerequest.h:474
QgsFeatureRequest::filterType
FilterType filterType() const
Returns the attribute/ID filter type which is currently set on this request.
Definition: qgsfeaturerequest.h:355
QgsAbstractFeatureIterator::mClosed
bool mClosed
Sets to true, as soon as the iterator is closed.
Definition: qgsfeatureiterator.h:181
QgsFeatureRequest::FilterFids
@ FilterFids
Filter using feature IDs.
Definition: qgsfeaturerequest.h:118
QgsVectorLayerCache::sourceCrs
QgsCoordinateReferenceSystem sourceCrs() const
Returns the coordinate reference system for features in the cache.
Definition: qgsvectorlayercache.cpp:197
QgsFeature::geometry
QgsGeometry geometry
Definition: qgsfeature.h:71
QgsFeature::setValid
void setValid(bool validity)
Sets the validity of the feature.
Definition: qgsfeature.cpp:221
QgsFeatureRequest::destinationCrs
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for feature's geometries, or an invalid QgsCoordi...
Definition: qgsfeaturerequest.cpp:291
QgsAbstractFeatureIterator::mRequest
QgsFeatureRequest mRequest
A copy of the feature request.
Definition: qgsfeatureiterator.h:178
qgscachedfeatureiterator.h
QgsCachedFeatureIterator::close
bool close() override
Close this iterator.
Definition: qgscachedfeatureiterator.cpp:138
QgsCachedFeatureIterator::fetchFeature
bool fetchFeature(QgsFeature &f) override
Implementation for fetching a feature.
Definition: qgscachedfeatureiterator.cpp:95
QgsFeatureRequest::setFilterRect
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
Definition: qgsfeaturerequest.cpp:101
QgsFeature::id
QgsFeatureId id
Definition: qgsfeature.h:68
QgsAbstractFeatureIterator::filterRectToSourceCrs
QgsRectangle filterRectToSourceCrs(const QgsCoordinateTransform &transform) const SIP_THROW(QgsCsException)
Returns a rectangle representing the original request's QgsFeatureRequest::filterRect().
Definition: qgsfeatureiterator.cpp:157
QgsFeatureRequest
This class wraps a request for features to a vector layer (or directly its vector data provider).
Definition: qgsfeaturerequest.h:83
qgsgeometryengine.h
QgsCsException
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:65
QgsCachedFeatureWriterIterator::close
bool close() override
Close this iterator.
Definition: qgscachedfeatureiterator.cpp:202
QgsFeatureRequest::distanceWithin
double distanceWithin() const
Returns the maximum distance from the referenceGeometry() of fetched features, if spatialFilterType()...
Definition: qgsfeaturerequest.h:456
QgsFeatureIterator::close
bool close()
Definition: qgsfeatureiterator.h:412
QgsCoordinateReferenceSystem::isValid
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
Definition: qgscoordinatereferencesystem.cpp:977
QgsGeometry::isEmpty
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
Definition: qgsgeometry.cpp:379
QgsVectorLayerCache::layer
QgsVectorLayer * layer()
Returns the layer to which this cache belongs.
Definition: qgsvectorlayercache.cpp:192
QgsAbstractFeatureIterator::geometryToDestinationCrs
void geometryToDestinationCrs(QgsFeature &feature, const QgsCoordinateTransform &transform) const
Transforms feature's geometry according to the specified coordinate transform.
Definition: qgsfeatureiterator.cpp:101
QgsGeometry::constGet
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:136
QgsFeatureRequest::spatialFilterType
Qgis::SpatialFilterType spatialFilterType() const
Returns the spatial filter type which is currently set on this request.
Definition: qgsfeaturerequest.h:369
qgsvectorlayer.h
QgsGeometry::createGeometryEngine
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine representing the specified geometry.
Definition: qgsgeometry.cpp:3972
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:399
QgsCachedFeatureWriterIterator::rewind
bool rewind() override
Rewind to the beginning of the iterator.
Definition: qgscachedfeatureiterator.cpp:196
Qgis::SpatialFilterType::BoundingBox
@ BoundingBox
Filter using a bounding box.
QgsCachedFeatureWriterIterator::fetchFeature
bool fetchFeature(QgsFeature &f) override
Implementation for fetching a feature.
Definition: qgscachedfeatureiterator.cpp:172
qgsexception.h
QgsFeature
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:55
QgsCachedFeatureIterator::rewind
bool rewind() override
Rewind to the beginning of the iterator.
Definition: qgscachedfeatureiterator.cpp:132
QgsCoordinateTransform
Class for doing transforms between two map coordinate systems.
Definition: qgscoordinatetransform.h:57
QgsAbstractFeatureIterator
Internal feature iterator to be implemented within data providers.
Definition: qgsfeatureiterator.h:28
QgsRectangle::isNull
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
Definition: qgsrectangle.h:479
QgsFeatureIterator::rewind
bool rewind()
Definition: qgsfeatureiterator.h:404
Qgis::SpatialFilterType::DistanceWithin
@ DistanceWithin
Filter by distance to reference geometry.
QgsFeatureRequest::referenceGeometry
QgsGeometry referenceGeometry() const
Returns the reference geometry used for spatial filtering of features.
Definition: qgsfeaturerequest.h:433
QgsCachedFeatureWriterIterator::QgsCachedFeatureWriterIterator
QgsCachedFeatureWriterIterator(QgsVectorLayerCache *vlCache, const QgsFeatureRequest &featureRequest)
This constructor creates a feature iterator, which queries the backend and caches retrieved features.
Definition: qgscachedfeatureiterator.cpp:145
QgsCachedFeatureIterator::QgsCachedFeatureIterator
QgsCachedFeatureIterator(QgsVectorLayerCache *vlCache, const QgsFeatureRequest &featureRequest)
This constructor creates a feature iterator, that delivers all cached features.
Definition: qgscachedfeatureiterator.cpp:22