Skip to content
Permalink
Browse files
Consider sublayers with unknown counts as incomplete details
  • Loading branch information
nyalldawson committed Jul 12, 2021
1 parent e685ad0 commit 3ff67896a5e916901e9ef52900cbb841ad6a7883
@@ -22,13 +22,16 @@ Contains utility functions for working with data providers.
%End
public:

static bool sublayerDetailsAreIncomplete( const QList< QgsProviderSublayerDetails > &details );
static bool sublayerDetailsAreIncomplete( const QList< QgsProviderSublayerDetails > &details, bool ignoreUnknownFeatureCount );
%Docstring
Returns ``True`` if the sublayer ``details`` are incomplete, and require a more in-depth
scan.

For instance, if the details contain any vector sublayers with unknown geometry types
then a query with the Qgis.SublayerQueryFlag.ResolveGeometryType flag is required.

If ``ignoreUnknownFeatureCount`` is ``True`` then sublayers with an unknown feature count
will not be considered as incomplete.
%End

};
@@ -17,14 +17,17 @@
#include "qgsproviderutils.h"
#include "qgsprovidersublayerdetails.h"

bool QgsProviderUtils::sublayerDetailsAreIncomplete( const QList<QgsProviderSublayerDetails> &details )
bool QgsProviderUtils::sublayerDetailsAreIncomplete( const QList<QgsProviderSublayerDetails> &details, bool ignoreUnknownFeatureCount )
{
for ( const QgsProviderSublayerDetails &sublayer : details )
{
switch ( sublayer.type() )
{
case QgsMapLayerType::VectorLayer:
if ( sublayer.wkbType() == QgsWkbTypes::Unknown )
if ( sublayer.wkbType() == QgsWkbTypes::Unknown
|| ( ignoreUnknownFeatureCount &&
( sublayer.featureCount() == static_cast< long long >( Qgis::FeatureCountState::Uncounted )
|| sublayer.featureCount() == static_cast< long long >( Qgis::FeatureCountState::UnknownCount ) ) ) )
return true;
break;

@@ -40,8 +40,11 @@ class CORE_EXPORT QgsProviderUtils
*
* For instance, if the details contain any vector sublayers with unknown geometry types
* then a query with the Qgis::SublayerQueryFlag::ResolveGeometryType flag is required.
*
* If \a ignoreUnknownFeatureCount is TRUE then sublayers with an unknown feature count
* will not be considered as incomplete.
*/
static bool sublayerDetailsAreIncomplete( const QList< QgsProviderSublayerDetails > &details );
static bool sublayerDetailsAreIncomplete( const QList< QgsProviderSublayerDetails > &details, bool ignoreUnknownFeatureCount );

};

@@ -40,13 +40,46 @@ def test_sublayerDetailsAreIncomplete(self):
self.assertEqual(sublayers[0].wkbType(), QgsWkbTypes.Unknown)

# need to resolve geometry types for complete details about this uri!
self.assertTrue(QgsProviderUtils.sublayerDetailsAreIncomplete(sublayers))
self.assertTrue(QgsProviderUtils.sublayerDetailsAreIncomplete(sublayers, False))
self.assertTrue(QgsProviderUtils.sublayerDetailsAreIncomplete(sublayers, True))

# retry with retrieving geometry types
sublayers = QgsProviderRegistry.instance().querySublayers(uri, Qgis.SublayerQueryFlag.ResolveGeometryType)
# now we have all the details
self.assertEqual(len(sublayers), 3)
self.assertFalse(QgsProviderUtils.sublayerDetailsAreIncomplete(sublayers))
self.assertFalse(QgsProviderUtils.sublayerDetailsAreIncomplete(sublayers, False))
self.assertFalse(QgsProviderUtils.sublayerDetailsAreIncomplete(sublayers, True))

# this geopackage file requires manually requesting feature counts
uri = unitTestDataPath() + '/mixed_layers.gpkg'

# surface scan only
sublayers = QgsProviderRegistry.instance().querySublayers(uri)
self.assertEqual(len(sublayers), 4)
self.assertEqual(sublayers[0].name(), 'band1')
self.assertEqual(sublayers[1].name(), 'band2')
self.assertEqual(sublayers[2].name(), 'points')
self.assertEqual(sublayers[2].featureCount(), Qgis.FeatureCountState.Uncounted)
self.assertEqual(sublayers[3].name(), 'lines')
self.assertEqual(sublayers[3].featureCount(), Qgis.FeatureCountState.Uncounted)

# need to count features for complete details about this uri!
self.assertTrue(QgsProviderUtils.sublayerDetailsAreIncomplete(sublayers, True))
# ...unless we are ignoring unknown feature counts, that is...
self.assertFalse(QgsProviderUtils.sublayerDetailsAreIncomplete(sublayers, False))

# retry with retrieving feature count
sublayers = QgsProviderRegistry.instance().querySublayers(uri, Qgis.SublayerQueryFlag.CountFeatures)
# now we have all the details
self.assertEqual(len(sublayers), 4)
self.assertFalse(QgsProviderUtils.sublayerDetailsAreIncomplete(sublayers, True))
self.assertFalse(QgsProviderUtils.sublayerDetailsAreIncomplete(sublayers, False))
self.assertEqual(sublayers[0].name(), 'band1')
self.assertEqual(sublayers[1].name(), 'band2')
self.assertEqual(sublayers[2].name(), 'points')
self.assertEqual(sublayers[2].featureCount(), 0)
self.assertEqual(sublayers[3].name(), 'lines')
self.assertEqual(sublayers[3].featureCount(), 6)


if __name__ == '__main__':

0 comments on commit 3ff6789

Please sign in to comment.