Skip to content

Commit

Permalink
Add api to allow raster layer renderers to create different legend no…
Browse files Browse the repository at this point in the history
…de types,

instead of forcing them to always use the solid color blocks created by QgsRasterSymbolLegendNode
  • Loading branch information
nyalldawson committed Dec 7, 2020
1 parent 2e83bcf commit 6932985
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 22 deletions.
12 changes: 12 additions & 0 deletions python/core/auto_generated/raster/qgsrasterrenderer.sip.in
Expand Up @@ -108,6 +108,18 @@ nodata values will be used.
virtual void legendSymbologyItems( QList< QPair< QString, QColor > > &symbolItems /Out/ ) const;
%Docstring
Gets symbology items if provided by renderer
%End

virtual QList<QgsLayerTreeModelLegendNode *> createLegendNodes( QgsLayerTreeLayer *nodeLayer ) /Factory/;
%Docstring
Creates a set of legend nodes representing the renderer.

The default implementation calls :py:func:`~QgsRasterRenderer.legendSymbologyItems` and creates corresponding legend nodes for each returned
symbology item.

Subclasses can override this to return more legend nodes which better represent the renderer.

.. versionadded:: 3.18
%End

virtual void readXml( const QDomElement &rendererElem );
Expand Down
24 changes: 2 additions & 22 deletions src/core/qgsmaplayerlegend.cpp
Expand Up @@ -27,6 +27,7 @@
#include "qgsdiagramrenderer.h"
#include "qgssymbollayerutils.h"
#include "qgspointcloudrenderer.h"
#include "qgsrasterrenderer.h"

QgsMapLayerLegend::QgsMapLayerLegend( QObject *parent )
: QObject( parent )
Expand Down Expand Up @@ -426,28 +427,7 @@ QList<QgsLayerTreeModelLegendNode *> QgsDefaultRasterLayerLegend::createLayerTre
nodes << new QgsWmsLegendNode( nodeLayer );
}

QgsLegendColorList rasterItemList = mLayer->legendSymbologyItems();
if ( rasterItemList.isEmpty() )
return nodes;

// Paletted raster may have many colors, for example UInt16 may have 65536 colors
// and it is very slow, so we limit max count
int count = 0;
int max_count = 1000;

for ( QgsLegendColorList::const_iterator itemIt = rasterItemList.constBegin();
itemIt != rasterItemList.constEnd(); ++itemIt, ++count )
{
nodes << new QgsRasterSymbolLegendNode( nodeLayer, itemIt->second, itemIt->first );

if ( count == max_count )
{
QString label = tr( "following %1 items\nnot displayed" ).arg( rasterItemList.size() - max_count );
nodes << new QgsSimpleLegendNode( nodeLayer, label );
break;
}
}

nodes.append( mLayer->renderer()->createLegendNodes( nodeLayer ) );
return nodes;
}

Expand Down
30 changes: 30 additions & 0 deletions src/core/raster/qgsrasterrenderer.cpp
Expand Up @@ -19,6 +19,7 @@
#include "qgsrastertransparency.h"

#include "qgssymbollayerutils.h"
#include "qgslayertreemodellegendnode.h"

#include <QCoreApplication>
#include <QDomDocument>
Expand Down Expand Up @@ -101,6 +102,35 @@ void QgsRasterRenderer::setRasterTransparency( QgsRasterTransparency *t )
mRasterTransparency = t;
}

QList<QgsLayerTreeModelLegendNode *> QgsRasterRenderer::createLegendNodes( QgsLayerTreeLayer *nodeLayer )
{
QList<QgsLayerTreeModelLegendNode *> nodes;

QList< QPair< QString, QColor > > rasterItemList;
legendSymbologyItems( rasterItemList );
if ( rasterItemList.isEmpty() )
return nodes;

// Paletted raster may have many colors, for example UInt16 may have 65536 colors
// and it is very slow, so we limit max count
int count = 0;
int max_count = 1000;

for ( auto itemIt = rasterItemList.constBegin(); itemIt != rasterItemList.constEnd(); ++itemIt, ++count )
{
nodes << new QgsRasterSymbolLegendNode( nodeLayer, itemIt->second, itemIt->first );

if ( count == max_count )
{
QString label = tr( "following %1 items\nnot displayed" ).arg( rasterItemList.size() - max_count );
nodes << new QgsSimpleLegendNode( nodeLayer, label );
break;
}
}

return nodes;
}

void QgsRasterRenderer::_writeXml( QDomDocument &doc, QDomElement &rasterRendererElem ) const
{
if ( rasterRendererElem.isNull() )
Expand Down
14 changes: 14 additions & 0 deletions src/core/raster/qgsrasterrenderer.h
Expand Up @@ -30,6 +30,8 @@ class QDomElement;
class QPainter;
class QgsRasterTransparency;
class QgsStyleEntityVisitorInterface;
class QgsLayerTreeModelLegendNode;
class QgsLayerTreeLayer;

/**
* \ingroup core
Expand Down Expand Up @@ -119,6 +121,18 @@ class CORE_EXPORT QgsRasterRenderer : public QgsRasterInterface
//! Gets symbology items if provided by renderer
virtual void legendSymbologyItems( QList< QPair< QString, QColor > > &symbolItems SIP_OUT ) const { Q_UNUSED( symbolItems ) }

/**
* Creates a set of legend nodes representing the renderer.
*
* The default implementation calls legendSymbologyItems() and creates corresponding legend nodes for each returned
* symbology item.
*
* Subclasses can override this to return more legend nodes which better represent the renderer.
*
* \since QGIS 3.18
*/
virtual QList<QgsLayerTreeModelLegendNode *> createLegendNodes( QgsLayerTreeLayer *nodeLayer ) SIP_FACTORY;

//! Sets base class members from xml. Usually called from create() methods of subclasses
void readXml( const QDomElement &rendererElem ) override;

Expand Down

0 comments on commit 6932985

Please sign in to comment.