Skip to content

Commit

Permalink
OAPIF get feature count from server without fetching all features
Browse files Browse the repository at this point in the history
  • Loading branch information
domi4484 committed Jan 31, 2023
1 parent f306546 commit aa729bc
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 16 deletions.
56 changes: 41 additions & 15 deletions src/providers/wfs/oapif/qgsoapifprovider.cpp
Expand Up @@ -214,28 +214,54 @@ QgsWkbTypes::Type QgsOapifProvider::wkbType() const

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


QgsFeature f;
QgsFeatureRequest request;
request.setNoAttributes();
auto iter = getFeatures( request );
long long count = 0;
bool countExact = true;
while ( iter.nextFeature( f ) )
if ( !mShared->mServerFilter.isEmpty() )
{
if ( count == 1000 ) // to avoid too long processing time
url += QStringLiteral( "&" );
url += mShared->mServerFilter;
}

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

mShared->setFeatureCount( itemsRequest.numberMatched(), true );
}
else // Otherwise the slow way until server side filtering is implemented
{
if ( mUpdateFeatureCountAtNextFeatureCountRequest )
{
mUpdateFeatureCountAtNextFeatureCountRequest = false;

QgsFeature f;
QgsFeatureRequest request;
request.setNoAttributes();
auto iter = getFeatures( request );
long long count = 0;
bool countExact = true;
while ( iter.nextFeature( f ) )
{
countExact = false;
break;
if ( count == 1000 ) // to avoid too long processing time
{
countExact = false;
break;
}
count ++;
}
count ++;
}

mShared->setFeatureCount( count, countExact );
mShared->setFeatureCount( count, countExact );
}
}

return mShared->getFeatureCount();
}

Expand Down
2 changes: 1 addition & 1 deletion src/providers/wfs/oapif/qgsoapifprovider.h
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 @@ -146,6 +146,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 @@ -165,6 +166,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 aa729bc

Please sign in to comment.