Skip to content

Commit

Permalink
Add QgsDataProvider::ReadFlag::SkipFeatureCount and implement it in O…
Browse files Browse the repository at this point in the history
…GR provider to avoid featureCount() to be called
  • Loading branch information
rouault committed Nov 12, 2020
1 parent c8510b1 commit 3260807
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 1 deletion.
1 change: 1 addition & 0 deletions python/core/auto_generated/qgsdataprovider.sip.in
Expand Up @@ -73,6 +73,7 @@ Abstract base class for spatial data provider implementations.
enum ReadFlag
{
FlagTrustDataSource,
SkipFeatureCount,
};
typedef QFlags<QgsDataProvider::ReadFlag> ReadFlags;

Expand Down
7 changes: 6 additions & 1 deletion src/core/providers/ogr/qgsogrprovider.cpp
Expand Up @@ -953,7 +953,8 @@ void QgsOgrProvider::addSubLayerDetailsToSubLayerList( int i, QgsOgrLayer *layer

QStringList QgsOgrProvider::subLayers() const
{
return _subLayers( true );
const bool withFeatureCount = ( mReadFlags & QgsDataProvider::SkipFeatureCount ) == 0;
return _subLayers( withFeatureCount );
}

QgsLayerMetadata QgsOgrProvider::layerMetadata() const
Expand Down Expand Up @@ -1604,6 +1605,10 @@ QgsWkbTypes::Type QgsOgrProvider::wkbType() const
*/
long QgsOgrProvider::featureCount() const
{
if ( ( mReadFlags & QgsDataProvider::SkipFeatureCount ) != 0 )
{
return QgsVectorDataProvider::UnknownCount;
}
if ( mRefreshFeatureCount )
{
mRefreshFeatureCount = false;
Expand Down
1 change: 1 addition & 0 deletions src/core/qgsdataprovider.h
Expand Up @@ -122,6 +122,7 @@ class CORE_EXPORT QgsDataProvider : public QObject
enum ReadFlag
{
FlagTrustDataSource = 1 << 0, //!< Trust datasource config (primary key unicity, geometry type and srid, etc). Improves provider load time by skipping expensive checks like primary key unicity, geometry type and srid and by using estimated metadata on data load. Since QGIS 3.16
SkipFeatureCount = 1 << 1, //!< Make featureCount() return -1 to indicate unknown, and subLayers() to return a unknown feature count as well. Since QGIS 3.18. Only implemented by OGR provider at time of writing.
};
Q_DECLARE_FLAGS( ReadFlags, ReadFlag )

Expand Down
20 changes: 20 additions & 0 deletions tests/src/python/test_provider_shapefile.py
Expand Up @@ -22,12 +22,14 @@
from osgeo import gdal
from qgis.core import (
QgsApplication,
QgsDataProvider,
QgsSettings,
QgsFeature,
QgsField,
QgsGeometry,
QgsVectorLayer,
QgsFeatureRequest,
QgsProviderRegistry,
QgsVectorDataProvider,
QgsWkbTypes,
QgsVectorLayerExporter,
Expand Down Expand Up @@ -1076,6 +1078,24 @@ def testEncoding(self):
self.assertTrue(vl.isValid())
self.assertEqual([f.attributes() for f in vl.dataProvider().getFeatures()], [['abcŐ'], ['abcŐabcŐabcŐ']])

def testSkipFeatureCountOnFeatureCount(self):
"""Test QgsDataProvider.SkipFeatureCount on featureCount()"""

testPath = TEST_DATA_DIR + '/' + 'lines.shp'
provider = QgsProviderRegistry.instance().createProvider('ogr', testPath, QgsDataProvider.ProviderOptions(), QgsDataProvider.SkipFeatureCount)
self.assertTrue(provider.isValid())
self.assertEqual(provider.featureCount(), QgsVectorDataProvider.UnknownCount)

def testSkipFeatureCountOnSubLayers(self):
"""Test QgsDataProvider.SkipFeatureCount on subLayers()"""

datasource = os.path.join(TEST_DATA_DIR, 'shapefile')
provider = QgsProviderRegistry.instance().createProvider('ogr', datasource, QgsDataProvider.ProviderOptions(), QgsDataProvider.SkipFeatureCount)
self.assertTrue(provider.isValid())
sublayers = provider.subLayers()
self.assertTrue(len(sublayers) > 1)
self.assertEqual(sublayers[0].split(QgsDataProvider.sublayerSeparator())[2], '-1')


if __name__ == '__main__':
unittest.main()

0 comments on commit 3260807

Please sign in to comment.