Branch data Line data Source code
1 : : /*************************************************************************** 2 : : * qgsfeaturepool.h * 3 : : * ------------------- * 4 : : * copyright : (C) 2014 by Sandro Mani / Sourcepole AG * 5 : : * email : smani@sourcepole.ch * 6 : : ***************************************************************************/ 7 : : 8 : : /*************************************************************************** 9 : : * * 10 : : * This program is free software; you can redistribute it and/or modify * 11 : : * it under the terms of the GNU General Public License as published by * 12 : : * the Free Software Foundation; either version 2 of the License, or * 13 : : * (at your option) any later version. * 14 : : * * 15 : : ***************************************************************************/ 16 : : 17 : : #ifndef QGS_FEATUREPOOL_H 18 : : #define QGS_FEATUREPOOL_H 19 : : 20 : : #include <QCache> 21 : : #include <QMutex> 22 : : #include <QPointer> 23 : : 24 : : #include "qgis_analysis.h" 25 : : #include "qgsfeature.h" 26 : : #include "qgsspatialindex.h" 27 : : #include "qgsfeaturesink.h" 28 : : #include "qgsvectorlayerfeatureiterator.h" 29 : : 30 : : /** 31 : : * \ingroup analysis 32 : : * \brief A feature pool is based on a vector layer and caches features. 33 : : * 34 : : * \note This class is a technology preview and unstable API. 35 : : * \since QGIS 3.4 36 : : */ 37 : : class ANALYSIS_EXPORT QgsFeaturePool : public QgsFeatureSink SIP_ABSTRACT 38 : : { 39 : : 40 : : public: 41 : : 42 : : /** 43 : : * Creates a new feature pool for \a layer. 44 : : */ 45 : : QgsFeaturePool( QgsVectorLayer *layer ); 46 : 61 : virtual ~QgsFeaturePool() = default; 47 : : 48 : : /** 49 : : * Retrieves the feature with the specified \a id into \a feature. 50 : : * It will be retrieved from the cache or from the underlying feature source if unavailable. 51 : : * If the feature is neither available from the cache nor from the source it will return FALSE. 52 : : */ 53 : : bool getFeature( QgsFeatureId id, QgsFeature &feature ); 54 : : 55 : : /** 56 : : * Gets features for the provided \a request. No features will be fetched 57 : : * from the cache and the request is sent directly to the underlying feature source. 58 : : * Results of the request are cached in the pool and the ids of all the features 59 : : * are returned. This is used to warm the cache for a particular area of interest 60 : : * (bounding box) or other set of features. 61 : : * This will get a new feature source from the source vector layer. 62 : : * This needs to be called from the main thread. 63 : : * If \a feedback is specified, the call may return if the feedback is canceled. 64 : : */ 65 : : QgsFeatureIds getFeatures( const QgsFeatureRequest &request, QgsFeedback *feedback = nullptr ) SIP_SKIP; 66 : : 67 : : /** 68 : : * Updates a feature in this pool. 69 : : * Implementations will update the feature on the layer or on the data provider. 70 : : */ 71 : : virtual void updateFeature( QgsFeature &feature ) = 0; 72 : : 73 : : /** 74 : : * Removes a feature from this pool. 75 : : * Implementations will remove the feature from the layer or from the data provider. 76 : : */ 77 : : virtual void deleteFeature( QgsFeatureId fid ) = 0; 78 : : 79 : : /** 80 : : * Returns the complete set of feature ids in this pool. 81 : : * Note that this concerns the features governed by this pool, which are not necessarily all cached. 82 : : * 83 : : * \note not available in Python bindings 84 : : */ 85 : : QgsFeatureIds allFeatureIds() const SIP_SKIP; 86 : : 87 : : /** 88 : : * Gets all feature ids in the bounding box \a rect. It will use a spatial index to 89 : : * determine the ids. 90 : : * 91 : : * \note not available in Python bindings 92 : : */ 93 : : QgsFeatureIds getIntersects( const QgsRectangle &rect ) const SIP_SKIP; 94 : : 95 : : /** 96 : : * Gets a pointer to the underlying layer. 97 : : * May return a ``NULLPTR`` if the layer has been deleted. 98 : : * This must only be called from the main thread. 99 : : */ 100 : : QgsVectorLayer *layer() const; 101 : : 102 : : /** 103 : : * Gets a QPointer to the underlying layer. 104 : : * Note that access to any methods of the object 105 : : * will need to be done on the main thread and 106 : : * the pointer will need to be checked for validity 107 : : * before usage. 108 : : * 109 : : * \note not available in Python bindings 110 : : */ 111 : : QPointer<QgsVectorLayer> layerPtr() const SIP_SKIP; 112 : : 113 : : /** 114 : : * The layer id of the layer. 115 : : */ 116 : : QString layerId() const; 117 : : 118 : : /** 119 : : * The geometry type of this layer. 120 : : */ 121 : : QgsWkbTypes::GeometryType geometryType() const; 122 : : 123 : : /** 124 : : * The coordinate reference system of this layer. 125 : : */ 126 : : QgsCoordinateReferenceSystem crs() const; 127 : : 128 : : /** 129 : : * Returns the name of the layer. 130 : : * 131 : : * Should be preferred over layer().name() because it can directly be run on 132 : : * the background thread. 133 : : */ 134 : : QString layerName() const; 135 : : 136 : : protected: 137 : : 138 : : /** 139 : : * Inserts a feature into the cache and the spatial index. 140 : : * To be used by implementations of ``addFeature``. 141 : : */ 142 : : void insertFeature( const QgsFeature &feature, bool skipLock = false ); 143 : : 144 : : /** 145 : : * Changes a feature in the cache and the spatial index. 146 : : * To be used by implementations of ``updateFeature``. 147 : : */ 148 : : void refreshCache( const QgsFeature &feature ); 149 : : 150 : : /** 151 : : * Removes a feature from the cache and the spatial index. 152 : : * To be used by implementations of ``deleteFeature``. 153 : : */ 154 : : void removeFeature( const QgsFeatureId featureId ); 155 : : 156 : : /** 157 : : * Sets all the feature ids governed by this feature pool. 158 : : * Should be called by subclasses constructor and whenever 159 : : * they insert a new feature. 160 : : * 161 : : * \note not available in Python bindings 162 : : */ 163 : : void setFeatureIds( const QgsFeatureIds &ids ) SIP_SKIP; 164 : : 165 : : /** 166 : : * Checks if the feature \a fid is cached. 167 : : * 168 : : * \note not available in Python bindings 169 : : * \since QGIS 3.4 170 : : */ 171 : : bool isFeatureCached( QgsFeatureId fid ) SIP_SKIP; 172 : : 173 : : private: 174 : : #ifdef SIP_RUN 175 : : QgsFeaturePool( const QgsFeaturePool &other ) 176 : : {} 177 : : #endif 178 : : 179 : : static const int CACHE_SIZE = 1000; 180 : : QCache<QgsFeatureId, QgsFeature> mFeatureCache; 181 : : QPointer<QgsVectorLayer> mLayer; 182 : : mutable QReadWriteLock mCacheLock; 183 : : QgsFeatureIds mFeatureIds; 184 : : QgsSpatialIndex mIndex; 185 : : QgsWkbTypes::GeometryType mGeometryType; 186 : : std::unique_ptr<QgsVectorLayerFeatureSource> mFeatureSource; 187 : : QString mLayerName; 188 : : }; 189 : : 190 : : #endif // QGS_FEATUREPOOL_H