Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsvectorlayerfeatureiterator.h 3 : : --------------------- 4 : : begin : Dezember 2012 5 : : copyright : (C) 2012 by Martin Dobias 6 : : email : wonder dot sk at gmail dot com 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 : : #ifndef QGSVECTORLAYERFEATUREITERATOR_H 16 : : #define QGSVECTORLAYERFEATUREITERATOR_H 17 : : 18 : : #include "qgis_core.h" 19 : : #include "qgis_sip.h" 20 : : #include "qgsfeatureiterator.h" 21 : : #include "qgsfields.h" 22 : : #include "qgscoordinatereferencesystem.h" 23 : : #include "qgsfeaturesource.h" 24 : : #include "qgsexpressioncontextscopegenerator.h" 25 : : 26 : : #include <QPointer> 27 : : #include <QSet> 28 : : #include <memory> 29 : : 30 : : typedef QMap<QgsFeatureId, QgsFeature> QgsFeatureMap SIP_SKIP; 31 : : 32 : : class QgsExpressionFieldBuffer; 33 : : class QgsVectorLayer; 34 : : class QgsVectorLayerEditBuffer; 35 : : class QgsVectorLayerJoinBuffer; 36 : : class QgsVectorLayerJoinInfo; 37 : : class QgsExpressionContext; 38 : : 39 : : class QgsVectorLayerFeatureIterator; 40 : : 41 : : #ifdef SIP_RUN 42 : : % ModuleHeaderCode 43 : : #include "qgsfeatureiterator.h" 44 : : % End 45 : : #endif 46 : : 47 : : /** 48 : : * \ingroup core 49 : : * \brief Partial snapshot of vector layer's state (only the members necessary for access to features) 50 : : */ 51 : : class CORE_EXPORT QgsVectorLayerFeatureSource : public QgsAbstractFeatureSource 52 : : { 53 : : public: 54 : : 55 : : /** 56 : : * Constructor for QgsVectorLayerFeatureSource. 57 : : * \param layer source layer 58 : : */ 59 : : explicit QgsVectorLayerFeatureSource( const QgsVectorLayer *layer ); 60 : : 61 : : //! QgsVectorLayerFeatureSource cannot be copied 62 : : QgsVectorLayerFeatureSource( const QgsVectorLayerFeatureSource &other ) = delete; 63 : : //! QgsVectorLayerFeatureSource cannot be copied 64 : : QgsVectorLayerFeatureSource &operator==( const QgsVectorLayerFeatureSource &other ) = delete; 65 : : 66 : : ~QgsVectorLayerFeatureSource() override; 67 : : 68 : : QgsFeatureIterator getFeatures( const QgsFeatureRequest &request = QgsFeatureRequest() ) override; 69 : : 70 : : friend class QgsVectorLayerFeatureIterator SIP_SKIP; 71 : : 72 : : /** 73 : : * Returns the fields that will be available for features that are retrieved from 74 : : * this source. 75 : : * 76 : : * \since QGIS 3.0 77 : : */ 78 : : QgsFields fields() const; 79 : : 80 : : /** 81 : : * Returns the coordinate reference system for features retrieved from this source. 82 : : * \since QGIS 3.0 83 : : */ 84 : : QgsCoordinateReferenceSystem crs() const; 85 : : 86 : : /** 87 : : * Returns the layer id of the source layer. 88 : : * 89 : : * \since QGIS 3.4 90 : : */ 91 : : QString id() const; 92 : : 93 : : protected: 94 : : 95 : : std::unique_ptr< QgsAbstractFeatureSource > mProviderFeatureSource; 96 : : std::unique_ptr< QgsVectorLayerJoinBuffer > mJoinBuffer; 97 : : std::unique_ptr< QgsExpressionFieldBuffer > mExpressionFieldBuffer; 98 : : 99 : : QgsFields mFields; 100 : : 101 : : QString mId; 102 : : 103 : : QgsExpressionContextScope mLayerScope; 104 : : 105 : : bool mHasEditBuffer; 106 : : 107 : : // A deep-copy is only performed, if the original maps change 108 : : // see here https://github.com/qgis/Quantum-GIS/pull/673 109 : : // for explanation 110 : : QgsFeatureMap mAddedFeatures; 111 : : QgsGeometryMap mChangedGeometries; 112 : : QgsFeatureIds mDeletedFeatureIds; 113 : : QList<QgsField> mAddedAttributes; 114 : : QgsChangedAttributesMap mChangedAttributeValues; 115 : : QgsAttributeList mDeletedAttributeIds; 116 : : 117 : : QgsCoordinateReferenceSystem mCrs; 118 : : 119 : : private: 120 : : #ifdef SIP_RUN 121 : : QgsVectorLayerFeatureSource( const QgsVectorLayerFeatureSource &other ); 122 : : #endif 123 : : }; 124 : : 125 : : /** 126 : : * \ingroup core 127 : : */ 128 : : class CORE_EXPORT QgsVectorLayerFeatureIterator : public QgsAbstractFeatureIteratorFromSource<QgsVectorLayerFeatureSource> 129 : : { 130 : : public: 131 : : QgsVectorLayerFeatureIterator( QgsVectorLayerFeatureSource *source, bool ownSource, const QgsFeatureRequest &request ); 132 : : 133 : : ~QgsVectorLayerFeatureIterator() override; 134 : : 135 : : //! reset the iterator to the starting position 136 : : bool rewind() override; 137 : : 138 : : //! end of iterating: free the resources / lock 139 : : bool close() override; 140 : : 141 : : void setInterruptionChecker( QgsFeedback *interruptionChecker ) override SIP_SKIP; 142 : : 143 : : /** 144 : : * Join information prepared for fast attribute id mapping in QgsVectorLayerJoinBuffer::updateFeatureAttributes(). 145 : : * Created in the select() method of QgsVectorLayerJoinBuffer for the joins that contain fetched attributes 146 : : */ 147 : 0 : struct CORE_EXPORT FetchJoinInfo 148 : : { 149 : : const QgsVectorLayerJoinInfo *joinInfo;//!< Canonical source of information about the join 150 : : QgsAttributeList attributes; //!< Attributes to fetch 151 : : QMap<int, int> attributesSourceToDestLayerMap SIP_SKIP; //!< Mapping from original attribute index to the joined layer index 152 : : int indexOffset; //!< At what position the joined fields start 153 : : QgsVectorLayer *joinLayer; //!< Resolved pointer to the joined layer 154 : : int targetField; //!< Index of field (of this layer) that drives the join 155 : : int joinField; //!< Index of field (of the joined layer) must have equal value 156 : : 157 : : void addJoinedAttributesCached( QgsFeature &f, const QVariant &joinValue ) const; 158 : : void addJoinedAttributesDirect( QgsFeature &f, const QVariant &joinValue ) const; 159 : : }; 160 : : 161 : : 162 : : bool isValid() const override; 163 : : 164 : : protected: 165 : : //! fetch next feature, return TRUE on success 166 : : bool fetchFeature( QgsFeature &feature ) override; 167 : : 168 : : /** 169 : : * Overrides default method as we only need to filter features in the edit buffer 170 : : * while for others filtering is left to the provider implementation. 171 : : */ 172 : 0 : bool nextFeatureFilterExpression( QgsFeature &f ) override { return fetchFeature( f ); } 173 : : 174 : : //! Setup the simplification of geometries to fetch using the specified simplify method 175 : : bool prepareSimplification( const QgsSimplifyMethod &simplifyMethod ) override; 176 : : 177 : : //! \note not available in Python bindings 178 : : void rewindEditBuffer() SIP_SKIP; 179 : : 180 : : //! \note not available in Python bindings 181 : : void prepareJoin( int fieldIdx ) SIP_SKIP; 182 : : 183 : : //! \note not available in Python bindings 184 : : void prepareExpression( int fieldIdx ) SIP_SKIP; 185 : : 186 : : //! \note not available in Python bindings 187 : : void prepareFields() SIP_SKIP; 188 : : 189 : : //! \note not available in Python bindings 190 : : void prepareField( int fieldIdx ) SIP_SKIP; 191 : : 192 : : //! \note not available in Python bindings 193 : : bool fetchNextAddedFeature( QgsFeature &f ) SIP_SKIP; 194 : : //! \note not available in Python bindings 195 : : bool fetchNextChangedGeomFeature( QgsFeature &f ) SIP_SKIP; 196 : : //! \note not available in Python bindings 197 : : bool fetchNextChangedAttributeFeature( QgsFeature &f ) SIP_SKIP; 198 : : //! \note not available in Python bindings 199 : : void useAddedFeature( const QgsFeature &src, QgsFeature &f ) SIP_SKIP; 200 : : //! \note not available in Python bindings 201 : : void useChangedAttributeFeature( QgsFeatureId fid, const QgsGeometry &geom, QgsFeature &f ) SIP_SKIP; 202 : : //! \note not available in Python bindings 203 : : bool nextFeatureFid( QgsFeature &f ) SIP_SKIP; 204 : : //! \note not available in Python bindings 205 : : void addJoinedAttributes( QgsFeature &f ) SIP_SKIP; 206 : : 207 : : /** 208 : : * Adds attributes that don't source from the provider but are added inside QGIS 209 : : * Includes 210 : : * 211 : : * - Joined fields 212 : : * - Expression fields 213 : : * 214 : : * \param f The feature will be modified 215 : : * \note not available in Python bindings 216 : : */ 217 : : void addVirtualAttributes( QgsFeature &f ) SIP_SKIP; 218 : : 219 : : /** 220 : : * Adds an expression based attribute to a feature 221 : : * \param f feature 222 : : * \param attrIndex attribute index 223 : : * \note not available in Python bindings 224 : : * \since QGIS 2.14 225 : : */ 226 : : void addExpressionAttribute( QgsFeature &f, int attrIndex ) SIP_SKIP; 227 : : 228 : : /** 229 : : * Update feature with uncommitted attribute updates. 230 : : * \note not available in Python bindings 231 : : */ 232 : : void updateChangedAttributes( QgsFeature &f ) SIP_SKIP; 233 : : 234 : : /** 235 : : * Update feature with uncommitted geometry updates. 236 : : * \note not available in Python bindings 237 : : */ 238 : : void updateFeatureGeometry( QgsFeature &f ) SIP_SKIP; 239 : : 240 : : QgsFeatureRequest mProviderRequest; 241 : : QgsFeatureIterator mProviderIterator; 242 : : QgsFeatureRequest mChangedFeaturesRequest; 243 : : QgsFeatureIterator mChangedFeaturesIterator; 244 : : 245 : : QgsRectangle mFilterRect; 246 : : QgsCoordinateTransform mTransform; 247 : : 248 : : // only related to editing 249 : : QSet<QgsFeatureId> mFetchConsidered; 250 : : QgsGeometryMap::ConstIterator mFetchChangedGeomIt; 251 : : QgsFeatureMap::ConstIterator mFetchAddedFeaturesIt; 252 : : 253 : : bool mFetchedFid; // when iterating by FID: indicator whether it has been fetched yet or not 254 : : 255 : : /** 256 : : * Information about joins used in the current select() statement. 257 : : * Allows faster mapping of attribute ids compared to mVectorJoins. 258 : : */ 259 : : QMap<const QgsVectorLayerJoinInfo *, QgsVectorLayerFeatureIterator::FetchJoinInfo> mFetchJoinInfo; 260 : : 261 : : QMap<int, QgsExpression *> mExpressionFieldInfo; 262 : : 263 : : bool mHasVirtualAttributes; 264 : : 265 : : private: 266 : : #ifdef SIP_RUN 267 : : QgsVectorLayerFeatureIterator( const QgsVectorLayerFeatureIterator &rhs ); 268 : : #endif 269 : : 270 : : void createExpressionContext(); 271 : : std::unique_ptr<QgsExpressionContext> mExpressionContext; 272 : : 273 : : QgsFeedback *mInterruptionChecker = nullptr; 274 : : 275 : : QList< int > mPreparedFields; 276 : : QList< int > mFieldsToPrepare; 277 : : 278 : : //! Join list sorted by dependency 279 : : QList< FetchJoinInfo > mOrderedJoinInfoList; 280 : : 281 : : /** 282 : : * Will always return TRUE. We assume that ordering has been done on provider level already. 283 : : * 284 : : */ 285 : : bool prepareOrderBy( const QList<QgsFeatureRequest::OrderByClause> &orderBys ) override; 286 : : 287 : : //! returns whether the iterator supports simplify geometries on provider side 288 : : bool providerCanSimplify( QgsSimplifyMethod::MethodType methodType ) const override; 289 : : 290 : : void createOrderedJoinList(); 291 : : 292 : : /** 293 : : * Performs any post-processing (such as transformation) and feature based validity checking, e.g. checking for geometry validity. 294 : : */ 295 : : bool postProcessFeature( QgsFeature &feature ); 296 : : 297 : : /** 298 : : * Checks a feature's geometry for validity, if requested in feature request. 299 : : */ 300 : : bool checkGeometryValidity( const QgsFeature &feature ); 301 : : 302 : : bool mDelegatedOrderByToProvider = false; 303 : : }; 304 : : 305 : : 306 : : 307 : : /** 308 : : * \class QgsVectorLayerSelectedFeatureSource 309 : : * \ingroup core 310 : : * \brief QgsFeatureSource subclass for the selected features from a QgsVectorLayer. 311 : : * \since QGIS 3.0 312 : : */ 313 : 0 : class CORE_EXPORT QgsVectorLayerSelectedFeatureSource : public QgsFeatureSource, public QgsExpressionContextScopeGenerator 314 : : { 315 : : public: 316 : : 317 : : /** 318 : : * Constructor for QgsVectorLayerSelectedFeatureSource, for selected features from the specified \a layer. 319 : : * The currently selected feature IDs are stored, so change to the layer selection after constructing 320 : : * the QgsVectorLayerSelectedFeatureSource will not be reflected. 321 : : */ 322 : : QgsVectorLayerSelectedFeatureSource( QgsVectorLayer *layer ); 323 : : 324 : : //! QgsVectorLayerSelectedFeatureSource cannot be copied 325 : : QgsVectorLayerSelectedFeatureSource( const QgsVectorLayerSelectedFeatureSource &other ) = delete; 326 : : //! QgsVectorLayerSelectedFeatureSource cannot be copied 327 : : QgsVectorLayerSelectedFeatureSource &operator==( const QgsVectorLayerSelectedFeatureSource &other ) = delete; 328 : : 329 : : QgsFeatureIterator getFeatures( const QgsFeatureRequest &request = QgsFeatureRequest() ) const override; 330 : : QgsCoordinateReferenceSystem sourceCrs() const override; 331 : : QgsFields fields() const override; 332 : : QgsWkbTypes::Type wkbType() const override; 333 : : long featureCount() const override; 334 : : QString sourceName() const override; 335 : : QgsExpressionContextScope *createExpressionContextScope() const override; 336 : : SpatialIndexPresence hasSpatialIndex() const override; 337 : : 338 : : private: 339 : : 340 : : #ifdef SIP_RUN 341 : : QgsVectorLayerSelectedFeatureSource( const QgsVectorLayerSelectedFeatureSource &other ); 342 : : #endif 343 : : 344 : : // ideally this wouldn't be mutable, but QgsVectorLayerFeatureSource has non-const getFeatures() 345 : : mutable QgsVectorLayerFeatureSource mSource; 346 : : QgsFeatureIds mSelectedFeatureIds; 347 : : QgsWkbTypes::Type mWkbType = QgsWkbTypes::Unknown; 348 : : QString mName; 349 : : QPointer< QgsVectorLayer > mLayer; 350 : : 351 : : }; 352 : : 353 : : ///@cond PRIVATE 354 : : 355 : : #ifndef SIP_RUN 356 : 0 : class QgsVectorLayerSelectedFeatureIterator : public QgsAbstractFeatureIterator 357 : : { 358 : : public: 359 : : 360 : : QgsVectorLayerSelectedFeatureIterator( const QgsFeatureIds &selectedFeatureIds, 361 : : const QgsFeatureRequest &request, 362 : : QgsVectorLayerFeatureSource &source ); 363 : : 364 : : bool rewind() override; 365 : : bool close() override; 366 : : 367 : : protected: 368 : : bool fetchFeature( QgsFeature &f ) override; 369 : : 370 : : private: 371 : : QgsFeatureIds mSelectedFeatureIds; 372 : : QgsFeatureIterator mIterator; 373 : : 374 : : }; 375 : : 376 : : #endif 377 : : 378 : : ///@endcond 379 : : 380 : : #endif // QGSVECTORLAYERFEATUREITERATOR_H