Skip to content

Commit 8c0a2b5

Browse files
committed
Further tweaks to QgsFeatureRequest API, support featureAtId
1 parent b863ca1 commit 8c0a2b5

File tree

3 files changed

+63
-25
lines changed

3 files changed

+63
-25
lines changed

src/core/qgsfeaturerequest.h

+53-11
Original file line numberDiff line numberDiff line change
@@ -3,52 +3,94 @@
33

44
#include <QFlags>
55

6+
#include "qgsfeature.h"
67
#include "qgsrectangle.h"
78

89
#include <QList>
910
typedef QList<int> QgsAttributeList;
1011

1112
/**
1213
* This class wraps a request for features to a vector layer (or directly its vector data provider).
14+
* The request may apply a filter to fetch only a particular subset of features. Currently supported filters:
15+
* - no filter - all features are returned
16+
* - feature id - only feature that matches given feature id is returned
17+
* - rectangle - only features that intersect given rectangle should be fetched. For the sake of speed,
18+
* the intersection is often done only using feature's bounding box. There is a flag
19+
* ExactIntersect that makes sure that only intersecting features will be returned.
20+
*
21+
* For efficiency, it is also possible to tell provider that some data is not required:
22+
* - NoGeometry flag
23+
* - SubsetOfAttributes flag
1324
*
1425
* The options may be chained, e.g.:
15-
* QgsFeatureRequest().setExtent(QgsRectangle(0,0,1,1)).setFlags(QgsFeatureRequest::ExactIntersect)
26+
* QgsFeatureRequest().setFilterRect(QgsRectangle(0,0,1,1)).setFlags(QgsFeatureRequest::ExactIntersect)
27+
*
28+
* Examples:
29+
* - fetch all features:
30+
* QgsFeatureRequest()
31+
* - fetch all features, only one attribute
32+
* QgsFeatureRequest().setSubsetOfAttributes(QStringList("myfield"), provider->fieldMap())
33+
* - fetch all features, without geometries
34+
* QgsFeatureRequest().setFlags(QgsFeatureRequest::NoGeometry)
35+
* - fetch only features from particular extent
36+
* QgsFeatureRequest().setFilterRect(QgsRectangle(0,0,1,1))
37+
* - fetch only one feature
38+
* QgsFeatureRequest().setFilterFid(45)
39+
*
1640
*/
1741
class QgsFeatureRequest
1842
{
1943
public:
2044
enum Flag
2145
{
22-
NoGeometry = 0x01, //!< Do not fetch geometry
23-
NoAttributes = 0x02, //!< Do not fetch any attributes
24-
ExactIntersect = 0x04 //!< Use exact geometry intersection (slower) instead of bounding boxes
46+
NoGeometry = 0x01, //!< Do not fetch geometry
47+
SubsetOfAttributes = 0x02, //!< Fetch only a subset of attributes (setSubsetOfAttributes sets this flag)
48+
ExactIntersect = 0x04 //!< Use exact geometry intersection (slower) instead of bounding boxes
2549
};
2650
Q_DECLARE_FLAGS( Flags, Flag )
2751

52+
enum FilterType
53+
{
54+
FilterNone, //!< No filter is applied
55+
FilterRect, //!< Filter using a rectangle
56+
FilterFid //!< Filter using feature ID
57+
};
58+
2859
//! construct a default request: for all features get attributes and geometries
2960
QgsFeatureRequest();
3061

62+
FilterType filterType() const { return mFilter; }
63+
3164
//! Set rectangle from which features will be taken. Empty rectangle removes the filter.
32-
QgsFeatureRequest& setExtent( const QgsRectangle& rect ) { mRect = rect; return *this; }
33-
const QgsRectangle& extent() const { return mRect; }
65+
//!
66+
QgsFeatureRequest& setFilterRect( const QgsRectangle& rect ) { mFilter = FilterRect; mFilterRect = rect; return *this; }
67+
const QgsRectangle& filterRect() const { return mFilterRect; }
68+
69+
//! Set feature ID that should be fetched.
70+
QgsFeatureRequest& setFilterFid( QgsFeatureId fid ) { mFilterFid = FilterFid; mFilterFid = fid; return *this; }
71+
const QgsFeatureId& filterFid() const { return mFilterFid; }
3472

3573
//! Set flags that affect how features will be fetched
3674
QgsFeatureRequest& setFlags( Flags flags ) { mFlags = flags; return *this; }
3775
const Flags& flags() const { return mFlags; }
3876

3977
//! Set a subset of attributes that will be fetched. Empty list means that all attributes are used.
4078
//! To disable fetching attributes, reset the FetchAttributes flag (which is set by default)
41-
QgsFeatureRequest& setAttributes( const QgsAttributeList& attrs ) { mAttrs = attrs; return *this; }
42-
const QgsAttributeList& attributes() const { return mAttrs; }
79+
QgsFeatureRequest& setSubsetOfAttributes( const QgsAttributeList& attrs ) { mFlags |= SubsetOfAttributes; mAttrs = attrs; return *this; }
80+
const QgsAttributeList& subsetOfAttributes() const { return mAttrs; }
4381

44-
// TODO: maybe set attributes as a list of strings?
82+
//! Set a subset of attributes by names that will be fetched
83+
QgsFeatureRequest& setSubsetOfAttributes( const QStringList& attrNames, const QgsFieldMap& fields );
4584

4685
// TODO: in future
47-
// void setExpression(const QString& expression);
86+
// void setFilterExpression(const QString& expression); // using QgsExpression
87+
// void setFilterNativeExpression(con QString& expr); // using provider's SQL (if supported)
4888
// void setLimit(int limit);
4989

5090
protected:
51-
QgsRectangle mRect;
91+
FilterType mFilter;
92+
QgsRectangle mFilterRect;
93+
QgsFeatureId mFilterFid;
5294
Flags mFlags;
5395
QgsAttributeList mAttrs;
5496
};

src/core/qgsvectordataprovider.cpp

+5-7
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,13 @@ QString QgsVectorDataProvider::storageType() const
4949
void QgsVectorDataProvider::select( const QgsFeatureRequest& request )
5050
{
5151
QgsAttributeList attrs;
52-
if ( !( request.flags() & QgsFeatureRequest::NoAttributes ) )
53-
{
54-
attrs = request.attributes();
55-
if ( attrs.isEmpty() ) // empty list = fetch all attributes
56-
attrs = attributeIndexes();
57-
}
52+
if ( !( request.flags() & QgsFeatureRequest::SubsetOfAttributes ) )
53+
attrs = request.subsetOfAttributes();
54+
else
55+
attrs = attributeIndexes();
5856
bool fetchGeom = !( request.flags() & QgsFeatureRequest::NoGeometry );
5957
bool exactIntersect = ( request.flags() & QgsFeatureRequest::ExactIntersect );
60-
select( attrs, request.extent(), fetchGeom, exactIntersect );
58+
select( attrs, request.filterRect(), fetchGeom, exactIntersect );
6159
}
6260

6361

src/core/qgsvectorlayer.cpp

+5-7
Original file line numberDiff line numberDiff line change
@@ -1748,15 +1748,13 @@ void QgsVectorLayer::select( QgsAttributeList attributes, QgsRectangle rect, boo
17481748
void QgsVectorLayer::select( const QgsFeatureRequest& request )
17491749
{
17501750
QgsAttributeList attrs;
1751-
if ( !( request.flags() & QgsFeatureRequest::NoAttributes ) )
1752-
{
1753-
attrs = request.attributes();
1754-
if ( attrs.isEmpty() ) // empty list = fetch all attributes
1755-
attrs = pendingAllAttributesList();
1756-
}
1751+
if ( !( request.flags() & QgsFeatureRequest::SubsetOfAttributes ) )
1752+
attrs = request.subsetOfAttributes();
1753+
else
1754+
attrs = pendingAllAttributesList();
17571755
bool fetchGeom = !( request.flags() & QgsFeatureRequest::NoGeometry );
17581756
bool exactIntersect = ( request.flags() & QgsFeatureRequest::ExactIntersect );
1759-
select( attrs, request.extent(), fetchGeom, exactIntersect );
1757+
select( attrs, request.filterRect(), fetchGeom, exactIntersect );
17601758
}
17611759

17621760

0 commit comments

Comments
 (0)