From 829942dd3ff8564bc95b772041ca246961827508 Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Fri, 26 Jan 2024 12:22:25 +0100 Subject: [PATCH] SERVER: fix getlegendgraphic with colorramp & JSON Fix #55651 Backported from master 7411e9bbb00 --- .../layertree/qgscolorramplegendnode.sip.in | 2 ++ src/core/layertree/qgscolorramplegendnode.cpp | 26 ++++++++++++++++ src/core/layertree/qgscolorramplegendnode.h | 1 + .../test_qgsserver_wms_getlegendgraphic.py | 30 +++++++++++++++++++ 4 files changed, 59 insertions(+) diff --git a/python/core/auto_generated/layertree/qgscolorramplegendnode.sip.in b/python/core/auto_generated/layertree/qgscolorramplegendnode.sip.in index cecf3885cce3..aae3ea644b28 100644 --- a/python/core/auto_generated/layertree/qgscolorramplegendnode.sip.in +++ b/python/core/auto_generated/layertree/qgscolorramplegendnode.sip.in @@ -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 diff --git a/src/core/layertree/qgscolorramplegendnode.cpp b/src/core/layertree/qgscolorramplegendnode.cpp index 03dee92a4a8a..3e502e705f83 100644 --- a/src/core/layertree/qgscolorramplegendnode.cpp +++ b/src/core/layertree/qgscolorramplegendnode.cpp @@ -25,6 +25,7 @@ #include "qgsnumericformat.h" #include +#include QgsColorRampLegendNode::QgsColorRampLegendNode( QgsLayerTreeLayer *nodeLayer, QgsColorRamp *ramp, const QString &minimumLabel, const QString &maximumLabel, QObject *parent ) : QgsLayerTreeModelLegendNode( nodeLayer, parent ) @@ -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(); + + 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; +} diff --git a/src/core/layertree/qgscolorramplegendnode.h b/src/core/layertree/qgscolorramplegendnode.h index 28b13235292b..2c6089235d30 100644 --- a/src/core/layertree/qgscolorramplegendnode.h +++ b/src/core/layertree/qgscolorramplegendnode.h @@ -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. diff --git a/tests/src/python/test_qgsserver_wms_getlegendgraphic.py b/tests/src/python/test_qgsserver_wms_getlegendgraphic.py index c1d0c211a015..bded48f6a0fc 100644 --- a/tests/src/python/test_qgsserver_wms_getlegendgraphic.py +++ b/tests/src/python/test_qgsserver_wms_getlegendgraphic.py @@ -37,6 +37,7 @@ QgsMarkerSymbol, QgsRuleBasedRenderer, QgsVectorLayer, + QgsRasterLayer, ) from qgis.server import ( @@ -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]+' @@ -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()