Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
QgsFeatureSource::hasFeatures() -> Yes, No, Maybe
This method allows to determine if a feature source has content or not
(or maybe).

This method works for "generator" sources as well as for "collection"
sources.

Collection sources like QgsVectorDataProvider which allow to easily and
in a cheap way determine if features are available can return
FeaturesAvailable or NoFeaturesAvailable, generators will return
FeaturesMaybeAvailable.

QgsVectorDataProvider also implements an empty() method.
  • Loading branch information
m-kuhn committed Jun 4, 2018
1 parent 3b35948 commit 5fb9d14
Show file tree
Hide file tree
Showing 9 changed files with 46 additions and 52 deletions.
22 changes: 7 additions & 15 deletions python/core/auto_generated/qgsfeaturesource.sip.in
Expand Up @@ -22,6 +22,12 @@ An interface for objects which provide features via a getFeatures method.
#include "qgsfeaturesource.h"
%End
public:
enum FeatureAvailability
{
NoFeaturesAvailable,
FeaturesAvailable,
FeaturesMaybeAvailable
};

virtual ~QgsFeatureSource();

Expand Down Expand Up @@ -68,24 +74,10 @@ Returns the number of features contained in the source, or -1
if the feature count is unknown.
%End

virtual bool empty() const;
virtual FeatureAvailability hasFeatures() const;
%Docstring
Determines if there are any features available in the source.

In case it is not known if there are features available, false is returned.
Use ``emptyUnknown()`` to determine if this value is reliable.

.. seealso:: :py:func:`QgsVectorDataProvider.empty`
information.

.. versionadded:: 3.2
%End

virtual bool emptyUnknown() const;
%Docstring
Returns true if the value returned by ``empty()`` may be wrong.
This depends on the dataprovider.

.. versionadded:: 3.2
%End

Expand Down
11 changes: 8 additions & 3 deletions python/core/auto_generated/qgsvectordataprovider.sip.in
Expand Up @@ -131,12 +131,17 @@ Returns true if the layer contains at least one feature.
.. versionadded:: 3.2
%End

virtual bool emptyUnknown() const;
virtual QgsFeatureSource::FeatureAvailability hasFeatures() const;
%Docstring
For QgsVectorDataProviders this always returns true because
the provider is actually queried for features.
Will always return FeatureAvailability.FeaturesAvailable or
FeatureAvailability.FeaturesMaybeAvailable.

Calls empty() internally. Providers should override empty instead
if they provide an optimized version of this call.

.. versionadded:: 3.2

.. seealso:: :py:func:`empty`
%End

virtual QgsFields fields() const = 0;
Expand Down
4 changes: 2 additions & 2 deletions python/core/auto_generated/qgsvectorlayer.sip.in
Expand Up @@ -939,10 +939,10 @@ calculated by countSymbolFeatures()
:return: number of features rendered by symbol or -1 if failed or counts are not available
%End

virtual bool empty() const;
virtual FeatureAvailability hasFeatures() const;

%Docstring
Determines if this vector layer is empty.
Determines if this vector layer has features.

.. warning::

Expand Down
9 changes: 2 additions & 7 deletions src/core/qgsfeaturesource.cpp
Expand Up @@ -23,14 +23,9 @@
#include "qgsvectorlayer.h"
#include "qgsvectordataprovider.h"

bool QgsFeatureSource::empty() const
QgsFeatureSource::FeatureAvailability QgsFeatureSource::hasFeatures() const
{
return featureCount();
}

bool QgsFeatureSource::emptyUnknown() const
{
return featureCount() == -1;
return FeaturesMaybeAvailable;
}

QSet<QVariant> QgsFeatureSource::uniqueValues( int fieldIndex, int limit ) const
Expand Down
22 changes: 7 additions & 15 deletions src/core/qgsfeaturesource.h
Expand Up @@ -37,6 +37,12 @@ class QgsFeedback;
class CORE_EXPORT QgsFeatureSource
{
public:
enum FeatureAvailability
{
NoFeaturesAvailable, //!< There are certainly no features available in this source
FeaturesAvailable, //!< There is at least one feature available in this source
FeaturesMaybeAvailable //!< There may be features available in this source
};

virtual ~QgsFeatureSource() = default;

Expand Down Expand Up @@ -88,23 +94,9 @@ class CORE_EXPORT QgsFeatureSource
/**
* Determines if there are any features available in the source.
*
* In case it is not known if there are features available, false is returned.
* Use ``emptyUnknown()`` to determine if this value is reliable.
*
* \see QgsVectorDataProvider::empty() for data provider specific
* information.
*
* \since QGIS 3.2
*/
virtual bool empty() const;

/**
* Returns true if the value returned by ``empty()`` may be wrong.
* This depends on the dataprovider.
*
* \since QGIS 3.2
*/
virtual bool emptyUnknown() const;
virtual FeatureAvailability hasFeatures() const;

/**
* Returns the set of unique values contained within the specified \a fieldIndex from this source.
Expand Down
7 changes: 5 additions & 2 deletions src/core/qgsvectordataprovider.cpp
Expand Up @@ -59,9 +59,12 @@ bool QgsVectorDataProvider::empty() const
return false;
}

bool QgsVectorDataProvider::emptyUnknown() const
QgsFeatureSource::FeatureAvailability QgsVectorDataProvider::hasFeatures() const
{
return false;
if ( empty() )
return QgsFeatureSource::FeatureAvailability::NoFeaturesAvailable;
else
return QgsFeatureSource::FeatureAvailability::FeaturesAvailable;
}

QgsCoordinateReferenceSystem QgsVectorDataProvider::sourceCrs() const
Expand Down
12 changes: 8 additions & 4 deletions src/core/qgsvectordataprovider.h
Expand Up @@ -168,15 +168,19 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider, public QgsFeat
*
* \since QGIS 3.2
*/
virtual bool empty() const override;
virtual bool empty() const;

/**
* For QgsVectorDataProviders this always returns true because
* the provider is actually queried for features.
* Will always return FeatureAvailability::FeaturesAvailable or
* FeatureAvailability::FeaturesMaybeAvailable.
*
* Calls empty() internally. Providers should override empty instead
* if they provide an optimized version of this call.
*
* \since QGIS 3.2
* \see empty()
*/
virtual bool emptyUnknown() const override;
virtual QgsFeatureSource::FeatureAvailability hasFeatures() const override;

/**
* Returns the fields associated with this data provider.
Expand Down
7 changes: 5 additions & 2 deletions src/core/qgsvectorlayer.cpp
Expand Up @@ -2765,9 +2765,12 @@ long QgsVectorLayer::featureCount() const
( mEditBuffer ? mEditBuffer->mAddedFeatures.size() - mEditBuffer->mDeletedFeatureIds.size() : 0 );
}

bool QgsVectorLayer::empty() const
QgsFeatureSource::FeatureAvailability QgsVectorLayer::hasFeatures() const
{
return mDataProvider->empty() && ( !mEditBuffer || mEditBuffer->addedFeatures().empty() );
if ( mDataProvider->empty() && ( !mEditBuffer || mEditBuffer->addedFeatures().empty() ) )
return QgsFeatureSource::FeatureAvailability::NoFeaturesAvailable;
else
return QgsFeatureSource::FeatureAvailability::FeaturesAvailable;
}

bool QgsVectorLayer::commitChanges()
Expand Down
4 changes: 2 additions & 2 deletions src/core/qgsvectorlayer.h
Expand Up @@ -930,7 +930,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
long featureCount( const QString &legendKey ) const;

/**
* Determines if this vector layer is empty.
* Determines if this vector layer has features.
*
* \warning A layer is considered empty if neither the data provider nor
* the edit buffer have features in them.
Expand All @@ -940,7 +940,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
*
* \since QGIS 3.2
*/
bool empty() const override;
FeatureAvailability hasFeatures() const override;

/**
* Update the data source of the layer. The layer's renderer and legend will be preserved only
Expand Down

0 comments on commit 5fb9d14

Please sign in to comment.