28QgsSensorThingsFeatureSource::QgsSensorThingsFeatureSource(
const std::shared_ptr<QgsSensorThingsSharedData> &sharedData )
29 : mSharedData( sharedData )
35 return QgsFeatureIterator(
new QgsSensorThingsFeatureIterator(
this,
false, request ) );
38QgsSensorThingsSharedData *QgsSensorThingsFeatureSource::sharedData()
const
40 return mSharedData.get();
48QgsSensorThingsFeatureIterator::QgsSensorThingsFeatureIterator( QgsSensorThingsFeatureSource *source,
bool ownSource,
const QgsFeatureRequest &request )
50 , mInterruptionChecker( request.feedback() )
52 mTransform = mRequest.calculateTransform( mSource->sharedData()->crs() );
55 mFilterRect = filterRectToSourceCrs( mTransform );
56 if ( !mRequest.filterRect().isNull() && mFilterRect.isNull() )
72 requestIds = mRequest.filterFids();
76 requestIds.insert( mRequest.filterFid() );
79 if ( !mFilterRect.isNull() )
85 mDeferredFeaturesInFilterRectCheck = true;
89 switch ( mRequest.spatialFilterType() )
91 case Qgis::SpatialFilterType::NoFilter:
92 case Qgis::SpatialFilterType::BoundingBox:
95 case Qgis::SpatialFilterType::DistanceWithin:
96 if ( !mRequest.referenceGeometry().isEmpty() )
98 mDistanceWithinGeom = mRequest.referenceGeometry();
99 mDistanceWithinEngine.reset( QgsGeometry::createGeometryEngine( mDistanceWithinGeom.constGet() ) );
100 mDistanceWithinEngine->prepareGeometry();
105 mRequestFeatureIdList = qgis::setToList( requestIds );
106 std::sort( mRequestFeatureIdList.begin(), mRequestFeatureIdList.end() );
107 mRemainingFeatureIds = mRequestFeatureIdList;
108 if ( !mRemainingFeatureIds.empty() )
109 mFeatureIterator = mRemainingFeatureIds.at( 0 );
111 mGeometryTestFilterRect = mFilterRect;
114QgsSensorThingsFeatureIterator::~QgsSensorThingsFeatureIterator()
116 QgsSensorThingsFeatureIterator::close();
119bool QgsSensorThingsFeatureIterator::fetchFeature(
QgsFeature &f )
126 if ( mInterruptionChecker && mInterruptionChecker->isCanceled() )
129 if ( mDeferredFeaturesInFilterRectCheck || !mCurrentPage.isEmpty() )
131 const QgsFeatureIds featuresInRect = mSource->sharedData()->getFeatureIdsInExtent( mFilterRect, mInterruptionChecker, mCurrentPage, mNextPage, mAlreadyFetchedIds );
132 mCurrentPage.clear();
134 if ( !mRequestFeatureIdList.isEmpty() )
136 QgsFeatureIds requestIds = qgis::listToSet( mRequestFeatureIdList );
137 requestIds.intersect( featuresInRect );
138 mCurrentPageFeatureIdList = qgis::setToList( requestIds );
142 mCurrentPageFeatureIdList = qgis::setToList( featuresInRect );
144 if ( mCurrentPageFeatureIdList.empty() )
146 if ( mNextPage.isEmpty() )
152 mCurrentPage = mNextPage;
153 return fetchFeature( f );
157 std::sort( mCurrentPageFeatureIdList.begin(), mCurrentPageFeatureIdList.end() );
158 mRemainingFeatureIds = mCurrentPageFeatureIdList;
159 if ( !mRemainingFeatureIds.empty() )
160 mFeatureIterator = mRemainingFeatureIds.at( 0 );
162 mDeferredFeaturesInFilterRectCheck =
false;
172 if ( !mCurrentPageFeatureIdList.empty() && mRemainingFeatureIds.empty() )
174 if ( mNextPage.isEmpty() )
181 mCurrentPage = mNextPage;
182 return fetchFeature( f );
186 switch ( mRequest.filterType() )
190 if ( mRemainingFeatureIds.empty() )
193 bool result = mSource->sharedData()->getFeature( mRequest.filterFid(), f, mInterruptionChecker );
194 mAlreadyFetchedIds.insert( mRequest.filterFid() );
195 if ( mInterruptionChecker && mInterruptionChecker->isCanceled() )
198 geometryToDestinationCrs( f, mTransform );
199 if ( mDistanceWithinEngine && mDistanceWithinEngine->distance( f.
geometry().
constGet() ) > mRequest.distanceWithin() )
205 mRemainingFeatureIds.removeAll( f.
id() );
215 if ( mInterruptionChecker && mInterruptionChecker->isCanceled() )
218 if ( !mCurrentPageFeatureIdList.empty() && mRemainingFeatureIds.empty() )
220 if ( mNextPage.isEmpty() )
227 mCurrentPage = mNextPage;
228 return fetchFeature( f );
232 bool success = mSource->sharedData()->getFeature( mFeatureIterator, f, mInterruptionChecker );
233 mAlreadyFetchedIds.insert( mFeatureIterator );
235 if ( !mCurrentPageFeatureIdList.empty() )
237 mRemainingFeatureIds.removeAll( mFeatureIterator );
238 if ( !mRemainingFeatureIds.empty() )
239 mFeatureIterator = mRemainingFeatureIds.at( 0 );
248 if ( success && !mGeometryTestFilterRect.isNull() )
271 geometryToDestinationCrs( f, mTransform );
274 if ( mDistanceWithinEngine && mDistanceWithinEngine->distance( f.
geometry().
constGet() ) > mRequest.distanceWithin() )
287bool QgsSensorThingsFeatureIterator::rewind()
291 mFeatureIterator = 0;
292 mCurrentPage.clear();
293 mAlreadyFetchedIds.clear();
294 mRemainingFeatureIds = mRequestFeatureIdList;
295 if ( !mRemainingFeatureIds.empty() )
296 mFeatureIterator = mRemainingFeatureIds.at( 0 );
300bool QgsSensorThingsFeatureIterator::close()
309void QgsSensorThingsFeatureIterator::setInterruptionChecker(
QgsFeedback *interruptionChecker )
311 mInterruptionChecker = interruptionChecker;
@ Fid
Filter using feature ID.
@ Fids
Filter using feature IDs.
@ Expression
Filter using expression.
@ NoFilter
No filter is applied.
@ ExactIntersect
Use exact geometry intersection (slower) instead of bounding boxes.
@ BoundingBox
Filter using a bounding box.
Helper template that cares of two things: 1.
Custom exception class for Coordinate Reference System related exceptions.
Wrapper for iterator of features from vector data provider or vector layer.
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...
void setValid(bool validity)
Sets the validity of the feature.
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
bool boundingBoxIntersects(const QgsRectangle &rectangle) const
Returns true if the bounding box of this geometry intersects with a rectangle.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
bool intersects(const QgsRectangle &rectangle) const
Returns true if this geometry exactly intersects with a rectangle.
A rectangle specified with double values.
QSet< QgsFeatureId > QgsFeatureIds