Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[backport] SERVER: fix getlegendgraphic with colorramp & JSON #56257

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -55,6 +55,8 @@ Constructor for QgsColorRampLegendNode.

virtual QSizeF drawSymbolText( const QgsLegendSettings &settings, ItemContext *ctx, QSizeF symbolSize ) const;

virtual QJsonObject exportSymbolToJson( const QgsLegendSettings &settings, const QgsRenderContext &context ) const;


void setIconSize( QSize size );
%Docstring
Expand Down
26 changes: 26 additions & 0 deletions src/core/layertree/qgscolorramplegendnode.cpp
Expand Up @@ -25,6 +25,7 @@
#include "qgsnumericformat.h"

#include <QPalette>
#include <QBuffer>

QgsColorRampLegendNode::QgsColorRampLegendNode( QgsLayerTreeLayer *nodeLayer, QgsColorRamp *ramp, const QString &minimumLabel, const QString &maximumLabel, QObject *parent )
: QgsLayerTreeModelLegendNode( nodeLayer, parent )
Expand Down Expand Up @@ -476,3 +477,28 @@ QSizeF QgsColorRampLegendNode::drawSymbolText( const QgsLegendSettings &settings

return QSizeF( textWidth, textHeight );
}

QJsonObject QgsColorRampLegendNode::exportSymbolToJson( const QgsLegendSettings &settings, const QgsRenderContext &context ) const
{
Q_UNUSED( settings );
Q_UNUSED( context );

QJsonObject json;

const QPixmap icon = data( Qt::DecorationRole ).value<QPixmap>();

if ( ! icon.isNull() )
{
const QImage image( icon.toImage() );
QByteArray byteArray;
QBuffer buffer( &byteArray );
image.save( &buffer, "PNG" );
const QString base64 = QString::fromLatin1( byteArray.toBase64().data() );
json[ QStringLiteral( "icon" ) ] = base64;
}

json [ QStringLiteral( "min" ) ] = mMinimumValue;
json [ QStringLiteral( "max" ) ] = mMaximumValue;

return json;
}
1 change: 1 addition & 0 deletions src/core/layertree/qgscolorramplegendnode.h
Expand Up @@ -64,6 +64,7 @@ class CORE_EXPORT QgsColorRampLegendNode : public QgsLayerTreeModelLegendNode
QVariant data( int role ) const override;
QSizeF drawSymbol( const QgsLegendSettings &settings, ItemContext *ctx, double itemHeight ) const override;
QSizeF drawSymbolText( const QgsLegendSettings &settings, ItemContext *ctx, QSizeF symbolSize ) const override;
QJsonObject exportSymbolToJson( const QgsLegendSettings &settings, const QgsRenderContext &context ) const override;

/**
* Set the icon \a size, which controls how large the ramp will render in a layer tree widget.
Expand Down
30 changes: 30 additions & 0 deletions tests/src/python/test_qgsserver_wms_getlegendgraphic.py
Expand Up @@ -37,6 +37,7 @@
QgsMarkerSymbol,
QgsRuleBasedRenderer,
QgsVectorLayer,
QgsRasterLayer,
)

from qgis.server import (
Expand All @@ -45,6 +46,10 @@
QgsServer,
)

from utilities import (
unitTestDataPath,
)

# Strip path and content length because path may vary
RE_STRIP_UNCHECKABLE = br'MAP=[^"]+|Content-Length: \d+'
RE_ATTRIBUTES = br'[^>\s]+=[^>\s]+'
Expand Down Expand Up @@ -1360,6 +1365,31 @@ def testLegendPlaceholderIcon(self):
r, h = self._result(self._execute_request(qs))
self._img_diff_error(r, h, "WMS_GetLegendGraphic_Legend_Placeholder_Icon")

def test_wms_GetLegendGraphic_JSON_raster_color_ramp(self):
"""Test raster color ramp legend in JSON format"""

project = QgsProject()

path = os.path.join(unitTestDataPath('raster'),
'byte.tif')

layer = QgsRasterLayer(path, "layer1")
self.assertTrue(layer.isValid())
project.addMapLayers([layer])

server = QgsServer()
request = QgsBufferServerRequest("/?SERVICE=WMS&VERSION=1.30&REQUEST=GetLegendGraphic" +
"&LAYERS=layer1" +
"&FORMAT=application/json")
response = QgsBufferServerResponse()
server.handleRequest(request, response, project)
j = json.loads(bytes(response.body()))
node = j
self.assertEqual(node['nodes'][0]['symbols'][0]['title'], 'Band 1 (Gray)')
self.assertEqual(node['nodes'][0]['symbols'][1]['max'], 255)
self.assertEqual(node['nodes'][0]['symbols'][1]['min'], 74)
self.assertNotEqual(node['nodes'][0]['symbols'][1]['icon'], '')


if __name__ == '__main__':
unittest.main()