Add capabilities for raster renderers

And selectively expose some of QgsRasterRendererRegistry to python
This commit is contained in:
Nyall Dawson 2024-03-18 12:08:21 +10:00 committed by Martin Dobias
parent b3d3a61d75
commit e9730b1bb3
13 changed files with 335 additions and 14 deletions

View File

@ -1279,6 +1279,14 @@ Qgis.RasterRendererFlag.baseClass = Qgis
Qgis.RasterRendererFlags.baseClass = Qgis
RasterRendererFlags = Qgis # dirty hack since SIP seems to introduce the flags in module
# monkey patching scoped based enum
Qgis.RasterRendererCapability.UsesMultipleBands.__doc__ = "The renderer utilizes multiple raster bands for color data (note that alpha bands are not considered for this capability)"
Qgis.RasterRendererCapability.__doc__ = "Raster renderer capabilities.\n\n.. versionadded:: 3.48\n\n" + '* ``UsesMultipleBands``: ' + Qgis.RasterRendererCapability.UsesMultipleBands.__doc__
# --
Qgis.RasterRendererCapability.baseClass = Qgis
Qgis.RasterRendererCapabilities = lambda flags=0: Qgis.RasterRendererCapability(flags)
Qgis.RasterRendererCapabilities.baseClass = Qgis
RasterRendererCapabilities = Qgis # dirty hack since SIP seems to introduce the flags in module
# monkey patching scoped based enum
Qgis.RasterAttributeTableFieldUsage.Generic.__doc__ = "Field usage Generic"
Qgis.RasterAttributeTableFieldUsage.PixelCount.__doc__ = "Field usage PixelCount"
Qgis.RasterAttributeTableFieldUsage.Name.__doc__ = "Field usage Name"

View File

@ -691,6 +691,14 @@ The development version
enum class RasterRendererCapability /BaseType=IntFlag/
{
UsesMultipleBands,
};
typedef QFlags<Qgis::RasterRendererCapability> RasterRendererCapabilities;
enum class RasterAttributeTableFieldUsage /BaseType=IntEnum/
{
Generic,
@ -2859,6 +2867,8 @@ QFlags<Qgis::ProjectReadFlag> operator|(Qgis::ProjectReadFlag f1, QFlags<Qgis::P
QFlags<Qgis::RasterRendererFlag> operator|(Qgis::RasterRendererFlag f1, QFlags<Qgis::RasterRendererFlag> f2);
QFlags<Qgis::RasterRendererCapability> operator|(Qgis::RasterRendererCapability f1, QFlags<Qgis::RasterRendererCapability> f2);
QFlags<Qgis::RasterTemporalCapabilityFlag> operator|(Qgis::RasterTemporalCapabilityFlag f1, QFlags<Qgis::RasterTemporalCapabilityFlag> f2);
QFlags<Qgis::RelationshipCapability> operator|(Qgis::RelationshipCapability f1, QFlags<Qgis::RelationshipCapability> f2);

View File

@ -0,0 +1,72 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/raster/qgsrasterrendererregistry.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
class QgsRasterRendererRegistry
{
%Docstring(signature="appended")
Registry for raster renderers.
:py:class:`QgsRasterRendererRegistry` is not usually directly created, but rather accessed through
:py:func:`QgsApplication.rasterRendererRegistry()`.
.. note::
Exposed to Python bindings in QGIS 3.38
%End
%TypeHeaderCode
#include "qgsrasterrendererregistry.h"
%End
public:
QgsRasterRendererRegistry();
%Docstring
Constructor for QgsRasterRendererRegistry.
QgsRasterRendererRegistry is not usually directly created, but rather accessed through
:py:func:`QgsApplication.rasterRendererRegistry()`.
The registry is pre-populated with standard raster renderers.
%End
QStringList renderersList() const;
%Docstring
Returns a list of the names of registered renderers.
%End
Qgis::RasterRendererCapabilities rendererCapabilities( const QString &rendererName ) const;
%Docstring
Returns the capabilities for the renderer with the specified name.
.. versionadded:: 3.38
%End
QgsRasterRenderer *defaultRendererForDrawingStyle( Qgis::RasterDrawingStyle drawingStyle, QgsRasterDataProvider *provider ) const /Factory/;
%Docstring
Creates a default renderer for a raster drawing style (considering user options such as default contrast enhancement).
Caller takes ownership.
%End
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/raster/qgsrasterrendererregistry.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/

View File

@ -642,6 +642,7 @@
%Include auto_generated/raster/qgsrasterpyramid.sip
%Include auto_generated/raster/qgsrasterrange.sip
%Include auto_generated/raster/qgsrasterrenderer.sip
%Include auto_generated/raster/qgsrasterrendererregistry.sip
%Include auto_generated/raster/qgsrasterrendererutils.sip
%Include auto_generated/raster/qgsrasterresamplefilter.sip
%Include auto_generated/raster/qgsrasterresampler.sip

View File

@ -1253,6 +1253,13 @@ Qgis.RasterRendererFlag.baseClass = Qgis
Qgis.RasterRendererFlags.baseClass = Qgis
RasterRendererFlags = Qgis # dirty hack since SIP seems to introduce the flags in module
# monkey patching scoped based enum
Qgis.RasterRendererCapability.UsesMultipleBands.__doc__ = "The renderer utilizes multiple raster bands for color data (note that alpha bands are not considered for this capability)"
Qgis.RasterRendererCapability.__doc__ = "Raster renderer capabilities.\n\n.. versionadded:: 3.48\n\n" + '* ``UsesMultipleBands``: ' + Qgis.RasterRendererCapability.UsesMultipleBands.__doc__
# --
Qgis.RasterRendererCapability.baseClass = Qgis
Qgis.RasterRendererCapabilities.baseClass = Qgis
RasterRendererCapabilities = Qgis # dirty hack since SIP seems to introduce the flags in module
# monkey patching scoped based enum
Qgis.RasterAttributeTableFieldUsage.Generic.__doc__ = "Field usage Generic"
Qgis.RasterAttributeTableFieldUsage.PixelCount.__doc__ = "Field usage PixelCount"
Qgis.RasterAttributeTableFieldUsage.Name.__doc__ = "Field usage Name"

View File

@ -691,6 +691,14 @@ The development version
enum class RasterRendererCapability
{
UsesMultipleBands,
};
typedef QFlags<Qgis::RasterRendererCapability> RasterRendererCapabilities;
enum class RasterAttributeTableFieldUsage
{
Generic,
@ -2859,6 +2867,8 @@ QFlags<Qgis::ProjectReadFlag> operator|(Qgis::ProjectReadFlag f1, QFlags<Qgis::P
QFlags<Qgis::RasterRendererFlag> operator|(Qgis::RasterRendererFlag f1, QFlags<Qgis::RasterRendererFlag> f2);
QFlags<Qgis::RasterRendererCapability> operator|(Qgis::RasterRendererCapability f1, QFlags<Qgis::RasterRendererCapability> f2);
QFlags<Qgis::RasterTemporalCapabilityFlag> operator|(Qgis::RasterTemporalCapabilityFlag f1, QFlags<Qgis::RasterTemporalCapabilityFlag> f2);
QFlags<Qgis::RelationshipCapability> operator|(Qgis::RelationshipCapability f1, QFlags<Qgis::RelationshipCapability> f2);

View File

@ -0,0 +1,72 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/raster/qgsrasterrendererregistry.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
class QgsRasterRendererRegistry
{
%Docstring(signature="appended")
Registry for raster renderers.
:py:class:`QgsRasterRendererRegistry` is not usually directly created, but rather accessed through
:py:func:`QgsApplication.rasterRendererRegistry()`.
.. note::
Exposed to Python bindings in QGIS 3.38
%End
%TypeHeaderCode
#include "qgsrasterrendererregistry.h"
%End
public:
QgsRasterRendererRegistry();
%Docstring
Constructor for QgsRasterRendererRegistry.
QgsRasterRendererRegistry is not usually directly created, but rather accessed through
:py:func:`QgsApplication.rasterRendererRegistry()`.
The registry is pre-populated with standard raster renderers.
%End
QStringList renderersList() const;
%Docstring
Returns a list of the names of registered renderers.
%End
Qgis::RasterRendererCapabilities rendererCapabilities( const QString &rendererName ) const;
%Docstring
Returns the capabilities for the renderer with the specified name.
.. versionadded:: 3.38
%End
QgsRasterRenderer *defaultRendererForDrawingStyle( Qgis::RasterDrawingStyle drawingStyle, QgsRasterDataProvider *provider ) const /Factory/;
%Docstring
Creates a default renderer for a raster drawing style (considering user options such as default contrast enhancement).
Caller takes ownership.
%End
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/raster/qgsrasterrendererregistry.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/

View File

@ -642,6 +642,7 @@
%Include auto_generated/raster/qgsrasterpyramid.sip
%Include auto_generated/raster/qgsrasterrange.sip
%Include auto_generated/raster/qgsrasterrenderer.sip
%Include auto_generated/raster/qgsrasterrendererregistry.sip
%Include auto_generated/raster/qgsrasterrendererutils.sip
%Include auto_generated/raster/qgsrasterresamplefilter.sip
%Include auto_generated/raster/qgsrasterresampler.sip

View File

@ -1163,6 +1163,25 @@ class CORE_EXPORT Qgis
Q_ENUM( RasterRendererFlag )
Q_FLAG( RasterRendererFlags )
/**
* Raster renderer capabilities.
*
* \since QGIS 3.48
*/
enum class RasterRendererCapability : int SIP_ENUM_BASETYPE( IntFlag )
{
UsesMultipleBands = 1 << 0, //!< The renderer utilizes multiple raster bands for color data (note that alpha bands are not considered for this capability)
};
Q_ENUM( RasterRendererCapability )
/**
* Raster renderer capabilities.
*
* \since QGIS 3.38
*/
Q_DECLARE_FLAGS( RasterRendererCapabilities, RasterRendererCapability )
Q_FLAG( RasterRendererCapabilities )
/**
* \brief The RasterAttributeTableFieldUsage enum represents the usage of a Raster Attribute Table field.
* \note Directly mapped from GDALRATFieldUsage enum values.
@ -4977,6 +4996,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::ProfileGeneratorFlags )
Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::ProjectCapabilities )
Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::ProjectReadFlags )
Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::RasterRendererFlags )
Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::RasterRendererCapabilities )
Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::RasterTemporalCapabilityFlags )
Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::RelationshipCapabilities )
Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::RenderContextFlags )

View File

@ -35,9 +35,10 @@
QgsRasterRendererRegistryEntry::QgsRasterRendererRegistryEntry( const QString &name, const QString &visibleName,
QgsRasterRendererCreateFunc rendererFunction,
QgsRasterRendererWidgetCreateFunc widgetFunction )
QgsRasterRendererWidgetCreateFunc widgetFunction, Qgis::RasterRendererCapabilities capabilities )
: name( name )
, visibleName( visibleName )
, capabilities( capabilities )
, rendererCreateFunction( rendererFunction )
, widgetCreateFunction( widgetFunction )
{
@ -52,7 +53,8 @@ QgsRasterRendererRegistry::QgsRasterRendererRegistry()
{
// insert items in a particular order, which is returned in renderersList()
insert( QgsRasterRendererRegistryEntry( QStringLiteral( "multibandcolor" ), QObject::tr( "Multiband color" ),
QgsMultiBandColorRenderer::create, nullptr ) );
QgsMultiBandColorRenderer::create, nullptr,
Qgis::RasterRendererCapability::UsesMultipleBands ) );
insert( QgsRasterRendererRegistryEntry( QStringLiteral( "paletted" ), QObject::tr( "Paletted/Unique values" ), QgsPalettedRasterRenderer::create, nullptr ) );
insert( QgsRasterRendererRegistryEntry( QStringLiteral( "singlebandgray" ), QObject::tr( "Singleband gray" ),
QgsSingleBandGrayRenderer::create, nullptr ) );
@ -109,6 +111,16 @@ QList< QgsRasterRendererRegistryEntry > QgsRasterRendererRegistry::entries() con
return result;
}
Qgis::RasterRendererCapabilities QgsRasterRendererRegistry::rendererCapabilities( const QString &rendererName ) const
{
const QHash< QString, QgsRasterRendererRegistryEntry >::const_iterator it = mEntries.constFind( rendererName );
if ( it != mEntries.constEnd() )
{
return it.value().capabilities;
}
return Qgis::RasterRendererCapabilities();
}
QgsRasterRenderer *QgsRasterRendererRegistry::defaultRendererForDrawingStyle( Qgis::RasterDrawingStyle drawingStyle, QgsRasterDataProvider *provider ) const
{
if ( !provider || provider->bandCount() < 1 )

View File

@ -18,11 +18,6 @@
#ifndef QGSRASTERRENDERERREGISTRY_H
#define QGSRASTERRENDERERREGISTRY_H
#define SIP_NO_FILE
#include "qgis_core.h"
#include "qgis.h"
#include <QHash>
@ -36,17 +31,26 @@ class QgsRasterRendererWidget;
class QgsRasterDataProvider;
class QgsRectangle;
#ifndef SIP_RUN
typedef QgsRasterRenderer *( *QgsRasterRendererCreateFunc )( const QDomElement &, QgsRasterInterface *input );
typedef QgsRasterRendererWidget *( *QgsRasterRendererWidgetCreateFunc )( QgsRasterLayer *, const QgsRectangle &extent );
/**
* \ingroup core
* \brief Registry for raster renderer entries.
*
* \note Not available in Python bindings
*/
struct CORE_EXPORT QgsRasterRendererRegistryEntry
{
/**
* Constructor for QgsRasterRendererRegistryEntry.
*
* Since QGIS 3.38, the \a capabilities argument can be used to specify renderer capabilities.
*/
QgsRasterRendererRegistryEntry( const QString &name, const QString &visibleName, QgsRasterRendererCreateFunc rendererFunction,
QgsRasterRendererWidgetCreateFunc widgetFunction );
QgsRasterRendererWidgetCreateFunc widgetFunction, Qgis::RasterRendererCapabilities capabilities = Qgis::RasterRendererCapabilities() );
/**
* Constructor for QgsRasterRendererRegistryEntry.
@ -54,11 +58,21 @@ struct CORE_EXPORT QgsRasterRendererRegistryEntry
QgsRasterRendererRegistryEntry() = default;
QString name;
QString visibleName; //visible (and translatable) name
/**
* Renderer capabilities.
*
* \since QGIS 3.38
*/
Qgis::RasterRendererCapabilities capabilities;
QIcon icon();
QgsRasterRendererCreateFunc rendererCreateFunction = nullptr ; //pointer to create function
QgsRasterRendererWidgetCreateFunc widgetCreateFunction = nullptr ; //pointer to create function for renderer widget
};
#endif
/**
* \ingroup core
* \brief Registry for raster renderers.
@ -66,25 +80,67 @@ struct CORE_EXPORT QgsRasterRendererRegistryEntry
* QgsRasterRendererRegistry is not usually directly created, but rather accessed through
* QgsApplication::rasterRendererRegistry().
*
* \note not available in Python bindings
* \note Exposed to Python bindings in QGIS 3.38
*/
class CORE_EXPORT QgsRasterRendererRegistry
{
public:
/**
* Constructor for QgsRasterRendererRegistry.
*
* QgsRasterRendererRegistry is not usually directly created, but rather accessed through
* QgsApplication::rasterRendererRegistry().
*
* The registry is pre-populated with standard raster renderers.
*/
QgsRasterRendererRegistry();
void insert( const QgsRasterRendererRegistryEntry &entry );
void insertWidgetFunction( const QString &rendererName, QgsRasterRendererWidgetCreateFunc func );
bool rendererData( const QString &rendererName, QgsRasterRendererRegistryEntry &data ) const;
/**
* Inserts a new \a entry into the registry.
*
* \note Not available in Python bindings
*/
void insert( const QgsRasterRendererRegistryEntry &entry ) SIP_SKIP;
/**
* Sets the widget creation function for a renderer.
*
* \note Not available in Python bindings
*/
void insertWidgetFunction( const QString &rendererName, QgsRasterRendererWidgetCreateFunc func ) SIP_SKIP;
/**
* Retrieves renderer data from the registry.
*
* \note Not available in Python bindings
*/
bool rendererData( const QString &rendererName, QgsRasterRendererRegistryEntry &data ) const SIP_SKIP;
/**
* Returns a list of the names of registered renderers.
*/
QStringList renderersList() const;
QList< QgsRasterRendererRegistryEntry > entries() const;
/**
* Returns the list of registered renderers.
*
* \note Not available in Python bindings
*/
QList< QgsRasterRendererRegistryEntry > entries() const SIP_SKIP;
/**
* Returns the capabilities for the renderer with the specified name.
*
* \since QGIS 3.38
*/
Qgis::RasterRendererCapabilities rendererCapabilities( const QString &rendererName ) const;
/**
* Creates a default renderer for a raster drawing style (considering user options such as default contrast enhancement).
* Caller takes ownership.
*/
QgsRasterRenderer *defaultRendererForDrawingStyle( Qgis::RasterDrawingStyle drawingStyle, QgsRasterDataProvider *provider ) const;
QgsRasterRenderer *defaultRendererForDrawingStyle( Qgis::RasterDrawingStyle drawingStyle, QgsRasterDataProvider *provider ) const SIP_FACTORY;
private:
QHash< QString, QgsRasterRendererRegistryEntry > mEntries;

View File

@ -264,6 +264,7 @@ ADD_PYTHON_TEST(PyQgsRasterColorRampShader test_qgsrastercolorrampshader.py)
ADD_PYTHON_TEST(PyQgsRasterLineSymbolLayer test_qgsrasterlinesymbollayer.py)
ADD_PYTHON_TEST(PyQgsRasterPipe test_qgsrasterpipe.py)
ADD_PYTHON_TEST(PyQgsRasterRange test_qgsrasterrange.py)
ADD_PYTHON_TEST(PyQgsRasterRendererRegistry test_qgsrasterrendererregistry.py)
ADD_PYTHON_TEST(PyQgsRasterRendererUtils test_qgsrasterrendererutils.py)
ADD_PYTHON_TEST(PyQgsRasterResampler test_qgsrasterresampler.py)
ADD_PYTHON_TEST(PyQgsRasterTransparency test_qgsrastertransparency.py)

View File

@ -0,0 +1,51 @@
"""QGIS Unit tests for QgsRasterRendererRegistry
.. note:: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
"""
from qgis.core import (
Qgis,
QgsRasterRendererRegistry
)
import unittest
from qgis.testing import start_app, QgisTestCase
from utilities import unitTestDataPath
# Convenience instances in case you may need them
# not used in this test
start_app()
TEST_DATA_DIR = unitTestDataPath()
class TestQgsRasterRendererRegistry(QgisTestCase):
def test_registered(self):
"""
Test that standard renderers are registered
"""
registry = QgsRasterRendererRegistry()
self.assertIn('multibandcolor', registry.renderersList())
self.assertIn('singlebandgray', registry.renderersList())
self.assertIn('singlebandpseudocolor', registry.renderersList())
self.assertIn('singlebandcolordata', registry.renderersList())
self.assertIn('hillshade', registry.renderersList())
self.assertIn('paletted', registry.renderersList())
self.assertIn('contour', registry.renderersList())
def test_capabilities(self):
"""
Test retrieving renderer capabilities
"""
registry = QgsRasterRendererRegistry()
self.assertFalse(registry.rendererCapabilities('not a renderer'))
self.assertEqual(registry.rendererCapabilities('multibandcolor'),
Qgis.RasterRendererCapability.UsesMultipleBands)
self.assertEqual(registry.rendererCapabilities('singlebandgray'),
Qgis.RasterRendererCapabilities())
if __name__ == '__main__':
unittest.main()