Allow QgsVectorDataProviders to create QgsFeatureRenderers

Implements https://github.com/qgis/QGIS-Enhancement-Proposals/issues/111

Adds support to QgsVectorDataProvider to create vector layer renderers
using provider-specific backend information.
This commit is contained in:
Nyall Dawson 2018-03-01 13:18:59 +10:00
parent b42c893bbc
commit 678f65853a
6 changed files with 79 additions and 3 deletions

18
python/core/qgsvectordataprovider.sip.in Normal file → Executable file
View File

@ -51,6 +51,7 @@ of feature and attribute information from a spatial datasource.
ReadLayerMetadata, ReadLayerMetadata,
WriteLayerMetadata, WriteLayerMetadata,
CancelSupport, CancelSupport,
CreateRenderer,
}; };
typedef QFlags<QgsVectorDataProvider::Capability> Capabilities; typedef QFlags<QgsVectorDataProvider::Capability> Capabilities;
@ -477,6 +478,23 @@ Must be implemented by providers that support saving and loading styles to db re
%Docstring %Docstring
It returns false by default. It returns false by default.
Must be implemented by providers that support delete styles from db returning true Must be implemented by providers that support delete styles from db returning true
%End
virtual QgsFeatureRenderer *createRenderer( const QVariantMap &configuration = QVariantMap() ) const;
%Docstring
Creates a new vector layer feature renderer, using provider backend specific information.
The ``configuration`` map can be used to pass provider-specific configuration maps to the provider to
allow customisation of the returned renderer. Support and format of ``configuration`` varies by provider.
When called with an empty ``configuration`` map the provider's default renderer will be returned.
This method returns a new renderer and the caller takes ownership of the returned object.
Only providers which report the CreateRenderer capability will return a feature renderer. Other
providers will return None.
.. versionadded:: 3.2
%End %End
static QVariant convertValue( QVariant::Type type, const QString &value ); static QVariant convertValue( QVariant::Type type, const QString &value );

View File

@ -936,6 +936,9 @@ data source
.. versionadded:: 2.10 .. versionadded:: 2.10
%End %End
virtual QString loadDefaultStyle( bool &resultFlag /Out/ );
QgsVectorLayerFeatureCounter *countSymbolFeatures(); QgsVectorLayerFeatureCounter *countSymbolFeatures();
%Docstring %Docstring
Count features for symbols. Count features for symbols.

View File

@ -681,6 +681,11 @@ bool QgsVectorDataProvider::isDeleteStyleFromDatabaseSupported() const
return false; return false;
} }
QgsFeatureRenderer *QgsVectorDataProvider::createRenderer( const QVariantMap & ) const SIP_FACTORY
{
return nullptr;
}
void QgsVectorDataProvider::pushError( const QString &msg ) const void QgsVectorDataProvider::pushError( const QString &msg ) const
{ {
QgsDebugMsg( msg ); QgsDebugMsg( msg );

19
src/core/qgsvectordataprovider.h Normal file → Executable file
View File

@ -40,6 +40,7 @@ typedef QHash<int, QString> QgsAttrPalIndexNameHash;
class QgsFeatureIterator; class QgsFeatureIterator;
class QgsTransaction; class QgsTransaction;
class QgsFeedback; class QgsFeedback;
class QgsFeatureRenderer;
#include "qgsfeaturerequest.h" #include "qgsfeaturerequest.h"
@ -91,6 +92,7 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider, public QgsFeat
ReadLayerMetadata = 1 << 21, //!< Provider can read layer metadata from data store. Since QGIS 3.0. See QgsDataProvider::layerMetadata() ReadLayerMetadata = 1 << 21, //!< Provider can read layer metadata from data store. Since QGIS 3.0. See QgsDataProvider::layerMetadata()
WriteLayerMetadata = 1 << 22, //!< Provider can write layer metadata to the data store. Since QGIS 3.0. See QgsDataProvider::writeLayerMetadata() WriteLayerMetadata = 1 << 22, //!< Provider can write layer metadata to the data store. Since QGIS 3.0. See QgsDataProvider::writeLayerMetadata()
CancelSupport = 1 << 23, //!< Supports interruption of pending queries from a separated thread. Since QGIS 3.2 CancelSupport = 1 << 23, //!< Supports interruption of pending queries from a separated thread. Since QGIS 3.2
CreateRenderer = 1 << 24, //!< Provider can create feature renderers using backend-specific formatting information. Since QGIS 3.2. See QgsVectorDataProvider::createRenderer().
}; };
Q_DECLARE_FLAGS( Capabilities, Capability ) Q_DECLARE_FLAGS( Capabilities, Capability )
@ -479,6 +481,23 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider, public QgsFeat
*/ */
virtual bool isDeleteStyleFromDatabaseSupported() const; virtual bool isDeleteStyleFromDatabaseSupported() const;
/**
* Creates a new vector layer feature renderer, using provider backend specific information.
*
* The \a configuration map can be used to pass provider-specific configuration maps to the provider to
* allow customisation of the returned renderer. Support and format of \a configuration varies by provider.
*
* When called with an empty \a configuration map the provider's default renderer will be returned.
*
* This method returns a new renderer and the caller takes ownership of the returned object.
*
* Only providers which report the CreateRenderer capability will return a feature renderer. Other
* providers will return nullptr.
*
* \since QGIS 3.2
*/
virtual QgsFeatureRenderer *createRenderer( const QVariantMap &configuration = QVariantMap() ) const;
static QVariant convertValue( QVariant::Type type, const QString &value ); static QVariant convertValue( QVariant::Type type, const QString &value );
/** /**

View File

@ -1465,10 +1465,22 @@ void QgsVectorLayer::setDataSource( const QString &dataSource, const QString &ba
// reset style if loading default style, style is missing, or geometry type has changed // reset style if loading default style, style is missing, or geometry type has changed
if ( !renderer() || !legend() || geomType != geometryType() || loadDefaultStyleFlag ) if ( !renderer() || !legend() || geomType != geometryType() || loadDefaultStyleFlag )
{ {
// check if there is a default style / propertysheet defined
// for this layer and if so apply it
bool defaultLoadedFlag = false; bool defaultLoadedFlag = false;
if ( loadDefaultStyleFlag )
if ( loadDefaultStyleFlag && isSpatial() && mDataProvider->capabilities() & QgsVectorDataProvider::CreateRenderer )
{
// first try to create a renderer directly from the data provider
std::unique_ptr< QgsFeatureRenderer > defaultRenderer( mDataProvider->createRenderer() );
if ( defaultRenderer )
{
defaultLoadedFlag = true;
setRenderer( defaultRenderer.release() );
}
}
// else check if there is a default style / propertysheet defined
// for this layer and if so apply it
if ( !defaultLoadedFlag && loadDefaultStyleFlag )
{ {
loadDefaultStyle( defaultLoadedFlag ); loadDefaultStyle( defaultLoadedFlag );
} }
@ -1486,6 +1498,23 @@ void QgsVectorLayer::setDataSource( const QString &dataSource, const QString &ba
emit repaintRequested(); emit repaintRequested();
} }
QString QgsVectorLayer::loadDefaultStyle( bool &resultFlag )
{
if ( isSpatial() && mDataProvider->capabilities() & QgsVectorDataProvider::CreateRenderer )
{
// first try to create a renderer directly from the data provider
std::unique_ptr< QgsFeatureRenderer > defaultRenderer( mDataProvider->createRenderer() );
if ( defaultRenderer )
{
resultFlag = true;
setRenderer( defaultRenderer.release() );
return QString();
}
}
return QgsMapLayer::loadDefaultStyle( resultFlag );
}
bool QgsVectorLayer::setDataProvider( QString const &provider ) bool QgsVectorLayer::setDataProvider( QString const &provider )
{ {

View File

@ -930,6 +930,8 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
*/ */
void setDataSource( const QString &dataSource, const QString &baseName, const QString &provider, bool loadDefaultStyleFlag = false ); void setDataSource( const QString &dataSource, const QString &baseName, const QString &provider, bool loadDefaultStyleFlag = false );
QString loadDefaultStyle( bool &resultFlag SIP_OUT ) override;
/** /**
* Count features for symbols. * Count features for symbols.
* The method will return the feature counter task. You will need to * The method will return the feature counter task. You will need to