Skip to content

Commit

Permalink
[OAPIF] faster way to get feature count (backport of #51590)
Browse files Browse the repository at this point in the history
  • Loading branch information
rouault authored and nyalldawson committed Oct 3, 2023
1 parent 941477b commit a8da6b6
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 3 deletions.
28 changes: 28 additions & 0 deletions src/providers/wfs/oapif/qgsoapifprovider.cpp
Expand Up @@ -269,6 +269,34 @@ QgsWkbTypes::Type QgsOapifProvider::wkbType() const

long long QgsOapifProvider::featureCount() const
{
// If no filter is set try the fast way of retrieving the feature count
if ( mSubsetString.isEmpty() )
{
QString url = mShared->mItemsUrl;
url += QLatin1String( "?limit=1" );
url = mShared->appendExtraQueryParameters( url );

if ( !mShared->mServerFilter.isEmpty() )
{
url += QLatin1Char( '&' );
url += mShared->mServerFilter;
}

QgsOapifItemsRequest itemsRequest( mShared->mURI.uri(), url );
if ( !itemsRequest.request( true, false ) )
return -1;
if ( itemsRequest.errorCode() != QgsBaseNetworkRequest::NoError )
return -1;

const long long featureCount = itemsRequest.numberMatched();
if ( featureCount >= 0 )
{
mShared->setFeatureCount( featureCount, true );
return featureCount;
}
}

// Retry the slow way by active filter or numberMatched parameter not sent from server
if ( mUpdateFeatureCountAtNextFeatureCountRequest )
{
mUpdateFeatureCountAtNextFeatureCountRequest = false;
Expand Down
6 changes: 3 additions & 3 deletions src/providers/wfs/oapif/qgsoapifprovider.h
Expand Up @@ -109,8 +109,8 @@ class QgsOapifProvider final: public QgsVectorDataProvider
//! Layer metadata
QgsLayerMetadata mLayerMetadata;

//! Set to true by setSubsetString() if updateFeatureCount is true
mutable bool mUpdateFeatureCountAtNextFeatureCountRequest = false;
//! Set to true by reloadProviderData()
mutable bool mUpdateFeatureCountAtNextFeatureCountRequest = true;

//! Initial requests
bool init();
Expand Down Expand Up @@ -212,7 +212,7 @@ class QgsOapifSharedData final: public QObject, public QgsBackgroundCachedShared

bool hasServerSideFilter() const override { return false; }

bool supportsFastFeatureCount() const override { return false; }
bool supportsFastFeatureCount() const override { return mURI.filter().isEmpty(); }

QgsRectangle getExtentFromSingleFeatureRequest() const override { return QgsRectangle(); }

Expand Down
5 changes: 5 additions & 0 deletions tests/src/python/test_provider_oapif.py
Expand Up @@ -162,6 +162,7 @@ def setUpClass(cls):

items = {
"type": "FeatureCollection",
"numberMatched": 5,
"features": [
{"type": "Feature", "id": "feat.1",
"properties": {"pk": 1, "cnt": 100, "name": "Orange", "name2": "oranGe", "num_char": "1", "dt": "2020-05-03 12:13:14", "date": "2020-05-03", "time": "12:13:14"},
Expand All @@ -181,6 +182,10 @@ def setUpClass(cls):
]
}

# limit 1 for getting count
with open(sanitize(endpoint, '/collections/mycollection/items?limit=1&' + ACCEPT_ITEMS), 'wb') as f:
f.write(json.dumps(items).encode('UTF-8'))

# first items
with open(sanitize(endpoint, '/collections/mycollection/items?limit=10&' + ACCEPT_ITEMS), 'wb') as f:
f.write(json.dumps(items).encode('UTF-8'))
Expand Down

0 comments on commit a8da6b6

Please sign in to comment.