From dae8447b0b1ddd8e2d28b0f70f9b665ca4f409ca Mon Sep 17 00:00:00 2001 From: Blottiere Paul Date: Thu, 8 Jun 2017 09:54:52 +0100 Subject: [PATCH 1/3] [Server] GetLegendGraphics refactoring --- src/server/services/wms/qgslayerrestorer.cpp | 14 +- src/server/services/wms/qgslayerrestorer.h | 1 + src/server/services/wms/qgswmsparameters.cpp | 528 ++++++++++++++- src/server/services/wms/qgswmsparameters.h | 331 +++++++++- src/server/services/wms/qgswmsrenderer.cpp | 661 ++++++------------- src/server/services/wms/qgswmsrenderer.h | 20 +- 6 files changed, 1042 insertions(+), 513 deletions(-) diff --git a/src/server/services/wms/qgslayerrestorer.cpp b/src/server/services/wms/qgslayerrestorer.cpp index 4e28fd62b94..78f9585121d 100644 --- a/src/server/services/wms/qgslayerrestorer.cpp +++ b/src/server/services/wms/qgslayerrestorer.cpp @@ -21,24 +21,15 @@ #include "qgsrasterrenderer.h" #include "qgsmaplayerstylemanager.h" -const QString DEFAULT_NAMED_STYLE = "server_default_style"; - QgsLayerRestorer::QgsLayerRestorer( const QList &layers ) { Q_FOREACH ( QgsMapLayer *layer, layers ) { QgsLayerSettings settings; + settings.name = layer->name(); QString style = layer->styleManager()->currentStyle(); - if ( style.isEmpty() ) - { - layer->styleManager()->addStyleFromLayer( DEFAULT_NAMED_STYLE ); - settings.mNamedStyle = DEFAULT_NAMED_STYLE; - } - else - { - settings.mNamedStyle = style; - } + settings.mNamedStyle = layer->styleManager()->currentStyle(); // set a custom property allowing to keep in memory if a SLD file has // been loaded for rendering @@ -80,6 +71,7 @@ QgsLayerRestorer::~QgsLayerRestorer() { QgsLayerSettings settings = mLayerSettings[layer]; layer->styleManager()->setCurrentStyle( settings.mNamedStyle ); + layer->setName( mLayerSettings[layer].name ); // if a SLD file has been loaded for rendering, we restore the previous one QString errMsg; diff --git a/src/server/services/wms/qgslayerrestorer.h b/src/server/services/wms/qgslayerrestorer.h index 2fb738c8049..199ab05a45a 100644 --- a/src/server/services/wms/qgslayerrestorer.h +++ b/src/server/services/wms/qgslayerrestorer.h @@ -30,6 +30,7 @@ class QgsLayerRestorer { struct QgsLayerSettings { + QString name; double mOpacity; QString mNamedStyle; QDomDocument mSldStyle; diff --git a/src/server/services/wms/qgswmsparameters.cpp b/src/server/services/wms/qgswmsparameters.cpp index 06e28e7b14a..90549ea7844 100644 --- a/src/server/services/wms/qgswmsparameters.cpp +++ b/src/server/services/wms/qgswmsparameters.cpp @@ -23,6 +23,90 @@ namespace QgsWms { QgsWmsParameters::QgsWmsParameters() { + const Parameter pBoxSpace = { ParameterName::BOXSPACE, + QVariant::Double, + QVariant( 2.0 ), + QVariant() + }; + save( pBoxSpace ); + + const Parameter pSymbSpace = { ParameterName::SYMBOLSPACE, + QVariant::Double, + QVariant( 2.0 ), + QVariant() + }; + save( pSymbSpace ); + + const Parameter pLayerSpace = { ParameterName::LAYERSPACE, + QVariant::Double, + QVariant( 3.0 ), + QVariant() + }; + save( pLayerSpace ); + + const Parameter pTitleSpace = { ParameterName::LAYERTITLESPACE, + QVariant::Double, + QVariant( 3.0 ), + QVariant() + }; + save( pTitleSpace ); + + const Parameter pSymbHeight = { ParameterName::SYMBOLHEIGHT, + QVariant::Double, + QVariant( 4.0 ), + QVariant() + }; + save( pSymbHeight ); + + const Parameter pSymbWidth = { ParameterName::SYMBOLWIDTH, + QVariant::Double, + QVariant( 7.0 ), + QVariant() + }; + save( pSymbWidth ); + + const Parameter pIcLabelSpace = { ParameterName::ICONLABELSPACE, + QVariant::Double, + QVariant( 2.0 ), + QVariant() + }; + save( pIcLabelSpace ); + + const Parameter pItFontFamily = { ParameterName::ITEMFONTFAMILY, + QVariant::String, + QVariant( "" ), + QVariant() + }; + save( pItFontFamily ); + + const Parameter pItFontBold = { ParameterName::ITEMFONTBOLD, + QVariant::Bool, + QVariant( false ), + QVariant() + }; + save( pItFontBold ); + + const Parameter pItFontItalic = { ParameterName::ITEMFONTITALIC, + QVariant::Bool, + QVariant( false ), + QVariant() + }; + save( pItFontItalic ); + + const Parameter pItFontSize = { ParameterName::ITEMFONTSIZE, + QVariant::Double, + QVariant( -1 ), + QVariant() + }; + save( pItFontSize ); + + const Parameter pItFontColor = { ParameterName::ITEMFONTCOLOR, + QVariant::String, + QVariant( "black" ), + QVariant() + }; + save( pItFontColor ); + const Parameter pHighlightGeom = { ParameterName::HIGHLIGHT_GEOM, QVariant::String, QVariant( "" ), @@ -30,6 +114,13 @@ namespace QgsWms }; save( pHighlightGeom ); + const Parameter pShowFeatureCount = { ParameterName::SHOWFEATURECOUNT, + QVariant::Bool, + QVariant( false ), + QVariant() + }; + save( pShowFeatureCount ); + const Parameter pHighlightSymbol = { ParameterName::HIGHLIGHT_SYMBOL, QVariant::String, QVariant( "" ), @@ -46,7 +137,7 @@ namespace QgsWms const Parameter pHighlightColor = { ParameterName::HIGHLIGHT_LABELCOLOR, QVariant::String, - QVariant( "" ), + QVariant( "black" ), QVariant() }; save( pHighlightColor ); @@ -74,7 +165,7 @@ namespace QgsWms const Parameter pHighlightBufferColor = { ParameterName::HIGHLIGHT_LABELBUFFERCOLOR, QVariant::String, - QVariant( "" ), + QVariant( "black" ), QVariant() }; save( pHighlightBufferColor ); @@ -93,6 +184,34 @@ namespace QgsWms }; save( pCRS ); + const Parameter pFormat = { ParameterName::FORMAT, + QVariant::String, + QVariant( "" ), + QVariant() + }; + save( pFormat ); + + const Parameter pRule = { ParameterName::RULE, + QVariant::String, + QVariant( "" ), + QVariant() + }; + save( pRule ); + + const Parameter pRuleLabel = { ParameterName::RULELABEL, + QVariant::Bool, + QVariant( true ), + QVariant() + }; + save( pRuleLabel ); + + const Parameter pScale = { ParameterName::SCALE, + QVariant::Double, + QVariant( "" ), + QVariant() + }; + save( pScale ); + const Parameter pHeight = { ParameterName::HEIGHT, QVariant::Int, QVariant( 0 ), @@ -135,6 +254,48 @@ namespace QgsWms }; save( pLayers ); + const Parameter pLayerTitle = { ParameterName::LAYERTITLE, + QVariant::Bool, + QVariant( true ), + QVariant() + }; + save( pLayerTitle ); + + const Parameter pLayerFtFamily = { ParameterName::LAYERFONTFAMILY, + QVariant::String, + QVariant( "" ), + QVariant() + }; + save( pLayerFtFamily ); + + const Parameter pLayerFtBold = { ParameterName::LAYERFONTBOLD, + QVariant::Bool, + QVariant( false ), + QVariant() + }; + save( pLayerFtBold ); + + const Parameter pLayerFtItalic = { ParameterName::LAYERFONTITALIC, + QVariant::Bool, + QVariant( false ), + QVariant() + }; + save( pLayerFtItalic ); + + const Parameter pLayerFtSize = { ParameterName::LAYERFONTSIZE, + QVariant::Double, + QVariant( -1 ), + QVariant() + }; + save( pLayerFtSize ); + + const Parameter pLayerFtColor = { ParameterName::LAYERFONTCOLOR, + QVariant::String, + QVariant( "black" ), + QVariant() + }; + save( pLayerFtColor ); + const Parameter pStyle = { ParameterName::STYLE, QVariant::String, QVariant( "" ), @@ -226,6 +387,11 @@ namespace QgsWms return mParameters[name].mValue; } + QVariant QgsWmsParameters::defaultValue( ParameterName name ) const + { + return mParameters[name].mDefaultValue; + } + QStringList QgsWmsParameters::highlightGeom() const { return toStringList( ParameterName::HIGHLIGHT_GEOM, ';' ); @@ -303,26 +469,77 @@ namespace QgsWms return extent; } - int QgsWmsParameters::height() const + QString QgsWmsParameters::height() const { - bool ok = false; - int height = value( ParameterName::HEIGHT ).toInt( &ok ); - - if ( ! ok ) - raiseError( ParameterName::HEIGHT ); - - return height; + return value( ParameterName::HEIGHT ).toString(); } - int QgsWmsParameters::width() const + QString QgsWmsParameters::width() const { - bool ok = false; - int width = value( ParameterName::WIDTH ).toInt( &ok ); + return value( ParameterName::WIDTH ).toString(); + } - if ( ! ok ) - raiseError( ParameterName::WIDTH ); + int QgsWmsParameters::heightAsInt() const + { + return toInt( ParameterName::HEIGHT ); + } - return width; + int QgsWmsParameters::widthAsInt() const + { + return toInt( ParameterName::WIDTH ); + } + + double QgsWmsParameters::toDouble( ParameterName p ) const + { + double val = defaultValue( p ).toDouble(); + QString valStr = value( p ).toString(); + + if ( ! valStr.isEmpty() ) + { + bool ok; + val = value( p ).toDouble( &ok ); + + if ( !ok ) + { + QString n = name( p ); + QString msg = n + " ('" + valStr + "') cannot be converted into a double"; + raiseError( msg ); + } + } + + return val; + } + + bool QgsWmsParameters::toBool( ParameterName p ) const + { + bool val = defaultValue( p ).toBool(); + QString valStr = value( p ).toString(); + + if ( ! valStr.isEmpty() ) + val = value( p ).toBool(); + + return val; + } + + int QgsWmsParameters::toInt( ParameterName p ) const + { + int val = defaultValue( p ).toInt(); + QString valStr = value( p ).toString(); + + if ( ! valStr.isEmpty() ) + { + bool ok; + val = value( p ).toInt( &ok ); + + if ( !ok ) + { + QString n = name( p ); + QString msg = n + " ('" + valStr + "') cannot be converted into int"; + raiseError( msg ); + } + } + + return val; } QStringList QgsWmsParameters::toStringList( ParameterName name, char delimiter ) const @@ -404,6 +621,285 @@ namespace QgsWms return elements; } + QString QgsWmsParameters::formatAsString() const + { + return value( ParameterName::FORMAT ).toString(); + } + + QgsWmsParameters::Format QgsWmsParameters::format() const + { + Format f = Format::PNG; + QString fStr = formatAsString(); + + if ( fStr.compare( QLatin1String( "jpg" ), Qt::CaseInsensitive ) == 0 + || fStr.compare( QLatin1String( "jpeg" ), Qt::CaseInsensitive ) == 0 + || fStr.compare( QLatin1String( "image/jpeg" ), Qt::CaseInsensitive ) == 0 ) + f = Format::JPG; + + return f; + } + + QString QgsWmsParameters::rule() const + { + return value( ParameterName::RULE ).toString(); + } + + QString QgsWmsParameters::ruleLabel() const + { + return value( ParameterName::RULELABEL ).toString(); + } + + bool QgsWmsParameters::ruleLabelAsBool() const + { + return toBool( ParameterName::RULELABEL ); + } + + QString QgsWmsParameters::scale() const + { + return value( ParameterName::SCALE ).toString(); + } + + double QgsWmsParameters::scaleAsDouble() const + { + return toDouble( ParameterName::SCALE ); + } + + QString QgsWmsParameters::showFeatureCount() const + { + return value( ParameterName::SHOWFEATURECOUNT ).toString(); + } + + bool QgsWmsParameters::showFeatureCountAsBool() const + { + return toBool( ParameterName::SHOWFEATURECOUNT ); + } + + QString QgsWmsParameters::boxSpace() const + { + return value( ParameterName::BOXSPACE ).toString(); + } + + double QgsWmsParameters::boxSpaceAsDouble() const + { + return toDouble( ParameterName::BOXSPACE ); + } + + QString QgsWmsParameters::layerSpace() const + { + return value( ParameterName::LAYERSPACE ).toString(); + } + + double QgsWmsParameters::layerSpaceAsDouble() const + { + return toDouble( ParameterName::LAYERSPACE ); + } + + QString QgsWmsParameters::layerTitleSpace() const + { + return value( ParameterName::LAYERTITLESPACE ).toString(); + } + + double QgsWmsParameters::layerTitleSpaceAsDouble() const + { + return toDouble( ParameterName::LAYERTITLESPACE ); + } + + QString QgsWmsParameters::symbolSpace() const + { + return value( ParameterName::SYMBOLSPACE ).toString(); + } + + double QgsWmsParameters::symbolSpaceAsDouble() const + { + return toDouble( ParameterName::SYMBOLSPACE ); + } + + QString QgsWmsParameters::symbolHeight() const + { + return value( ParameterName::SYMBOLHEIGHT ).toString(); + } + + double QgsWmsParameters::symbolHeightAsDouble() const + { + return toDouble( SYMBOLHEIGHT ); + } + + QString QgsWmsParameters::symbolWidth() const + { + return value( ParameterName::SYMBOLWIDTH ).toString(); + } + + double QgsWmsParameters::symbolWidthAsDouble() const + { + return toDouble( SYMBOLWIDTH ); + } + + QString QgsWmsParameters::iconLabelSpace() const + { + return value( ParameterName::ICONLABELSPACE ).toString(); + } + + double QgsWmsParameters::iconLabelSpaceAsDouble() const + { + return toDouble( ICONLABELSPACE ); + } + + QString QgsWmsParameters::layerFontFamily() const + { + return value( ParameterName::LAYERFONTFAMILY ).toString(); + } + + QString QgsWmsParameters::itemFontFamily() const + { + return value( ParameterName::ITEMFONTFAMILY ).toString(); + } + + QString QgsWmsParameters::layerFontBold() const + { + return value( ParameterName::LAYERFONTBOLD ).toString(); + } + + bool QgsWmsParameters::layerFontBoldAsBool() const + { + return toBool( ParameterName::LAYERFONTBOLD ); + } + + QString QgsWmsParameters::itemFontBold() const + { + return value( ParameterName::ITEMFONTBOLD ).toString(); + } + + bool QgsWmsParameters::itemFontBoldAsBool() const + { + return toBool( ParameterName::ITEMFONTBOLD ); + } + + QString QgsWmsParameters::layerFontItalic() const + { + return value( ParameterName::LAYERFONTITALIC ).toString(); + } + + bool QgsWmsParameters::layerFontItalicAsBool() const + { + return toBool( ParameterName::LAYERFONTITALIC ); + } + + QString QgsWmsParameters::itemFontItalic() const + { + return value( ParameterName::ITEMFONTITALIC ).toString(); + } + + bool QgsWmsParameters::itemFontItalicAsBool() const + { + return toBool( ParameterName::ITEMFONTITALIC ); + } + + QString QgsWmsParameters::layerFontSize() const + { + return value( ParameterName::LAYERFONTSIZE ).toString(); + } + + double QgsWmsParameters::layerFontSizeAsDouble() const + { + return toDouble( LAYERFONTSIZE ); + } + + QString QgsWmsParameters::layerFontColor() const + { + return value( ParameterName::LAYERFONTCOLOR ).toString(); + } + + QColor QgsWmsParameters::layerFontColorAsColor() const + { + ParameterName p = ParameterName::LAYERFONTCOLOR; + QColor c = defaultValue( p ).value(); + + if ( !layerFontColor().isEmpty() ) + { + c = QColor( layerFontColor() ); + + if ( !c.isValid() ) + { + QString val = value( p ).toString(); + QString n = name( p ); + QString msg = n + " ('" + val + "') cannot be converted into a color"; + raiseError( msg ); + } + } + + return c; + } + + QString QgsWmsParameters::itemFontSize() const + { + return value( ParameterName::ITEMFONTSIZE ).toString(); + } + + double QgsWmsParameters::itemFontSizeAsDouble() const + { + return toDouble( ITEMFONTSIZE ); + } + + QFont QgsWmsParameters::layerFont() const + { + QFont font; + font.fromString( "" ); + font.setBold( layerFontBoldAsBool() ); + font.setItalic( layerFontItalicAsBool() ); + + if ( ! layerFontSize().isEmpty() ) + font.setPointSizeF( layerFontSizeAsDouble() ); + + if ( !layerFontFamily().isEmpty() ) + font.setFamily( layerFontFamily() ); + + return font; + } + + QFont QgsWmsParameters::itemFont() const + { + QFont font; + font.fromString( "" ); + + font.setBold( itemFontBoldAsBool() ); + font.setItalic( itemFontItalicAsBool() ); + + if ( ! itemFontSize().isEmpty() ) + font.setPointSizeF( itemFontSizeAsDouble() ); + + if ( !itemFontFamily().isEmpty() ) + font.setFamily( itemFontFamily() ); + + return font; + } + + QString QgsWmsParameters::layerTitle() const + { + return value( ParameterName::LAYERTITLE ).toString(); + } + + bool QgsWmsParameters::layerTitleAsBool() const + { + return toBool( ParameterName::LAYERTITLE ); + } + + QgsLegendSettings QgsWmsParameters::legendSettings() const + { + QgsLegendSettings settings; + settings.setTitle( QString() ); + settings.setBoxSpace( boxSpaceAsDouble() ); + settings.setSymbolSize( QSizeF( symbolWidthAsDouble(), symbolHeightAsDouble() ) ); + + settings.rstyle( QgsLegendStyle::Subgroup ).setMargin( QgsLegendStyle::Top, layerSpaceAsDouble() ); + settings.rstyle( QgsLegendStyle::Subgroup ).setFont( layerFont() ); + + settings.rstyle( QgsLegendStyle::SymbolLabel ).setFont( itemFont() ); + settings.rstyle( QgsLegendStyle::Symbol ).setMargin( QgsLegendStyle::Top, symbolSpaceAsDouble() ); + settings.rstyle( QgsLegendStyle::SymbolLabel ).setMargin( QgsLegendStyle::Left, iconLabelSpaceAsDouble() ); + + return settings; + } + QStringList QgsWmsParameters::highlightLabelString() const { return toStringList( ParameterName::HIGHLIGHT_LABELSTRING, ';' ); diff --git a/src/server/services/wms/qgswmsparameters.h b/src/server/services/wms/qgswmsparameters.h index 40704709bfc..57bb800f4fa 100644 --- a/src/server/services/wms/qgswmsparameters.h +++ b/src/server/services/wms/qgswmsparameters.h @@ -25,6 +25,7 @@ #include "qgsrectangle.h" #include "qgswmsserviceexception.h" #include "qgsserverrequest.h" +#include "qgslegendsettings.h" #include "qgsgeometry.h" /** QgsWmsParameters provides an interface to retrieve and manipulate WMS @@ -63,18 +64,41 @@ namespace QgsWms public: enum ParameterName { + BOXSPACE, CRS, // instead of SRS for WMS 1.3.0 // SRS, // for WMS 1.1.1 WIDTH, HEIGHT, BBOX, + ICONLABELSPACE, + ITEMFONTFAMILY, + ITEMFONTBOLD, + ITEMFONTITALIC, + ITEMFONTSIZE, + ITEMFONTCOLOR, LAYER, + LAYERFONTFAMILY, + LAYERFONTBOLD, + LAYERFONTITALIC, + LAYERFONTSIZE, + LAYERFONTCOLOR, + LAYERTITLE, LAYERS, + LAYERSPACE, + LAYERTITLESPACE, + SHOWFEATURECOUNT, STYLE, STYLES, + SYMBOLSPACE, + SYMBOLHEIGHT, + SYMBOLWIDTH, OPACITIES, SLD, FILTER, + FORMAT, + RULE, + RULELABEL, + SCALE, SELECTION, HIGHLIGHT_GEOM, HIGHLIGHT_SYMBOL, @@ -88,6 +112,13 @@ namespace QgsWms }; Q_ENUM( ParameterName ) + enum Format + { + NONE, + JPG, + PNG + }; + struct Parameter { ParameterName mName; @@ -119,19 +150,31 @@ namespace QgsWms */ QString crs() const; - /** Returns WIDTH parameter as an int (0 if not defined). An exception is - * raised if it cannot be converted. + /** Returns WIDTH parameter or an empty string if not defined. + * \returns width parameter + */ + QString width() const; + + /** Returns WIDTH parameter as an int or its default value if not + * defined. An exception is raised if WIDTH is defined and cannot be + * converted. * \returns width parameter * \throws QgsBadRequestException */ - int width() const; + int widthAsInt() const; - /** Returns HEIGHT parameter as an int (0 if not defined). An exception - * is raised if it cannot be converted. + /** Returns HEIGHT parameter or an empty string if not defined. + * \returns height parameter + */ + QString height() const; + + /** Returns HEIGHT parameter as an int or its default value if not + * defined. An exception is raised if HEIGHT is defined and cannot be + * converted. * \returns height parameter * \throws QgsBadRequestException */ - int height() const; + int heightAsInt() const; /** Returns BBOX if defined or an empty string. * \returns bbox parameter @@ -188,6 +231,278 @@ namespace QgsWms */ QList layersParameters() const; + /** Returns FORMAT parameter as a string. + * \returns FORMAT parameter as string + */ + QString formatAsString() const; + + /** Returns format. If the FORMAT parameter is not used, then the + * default value is PNG. + * \returns format + */ + Format format() const; + + /** Returns RULE parameter or an empty string if none is defined + * \returns RULE parameter or an empty string if none is defined + */ + QString rule() const; + + /** Returns RULELABEL parameter or an empty string if none is defined + * \returns RULELABEL parameter or an empty string if none is defined + */ + QString ruleLabel() const; + + /** Returns RULELABEL as a bool. An exception is raised if an invalid + * parameter is found. + * \returns ruleLabel + * \throws QgsBadRequestException + */ + bool ruleLabelAsBool() const; + + /** Returns SHOWFEATURECOUNT parameter or an empty string if none is defined + * \returns SHOWFEATURECOUNT parameter or an empty string if none is defined + */ + QString showFeatureCount() const; + + /** Returns SHOWFEATURECOUNT as a bool. An exception is raised if an invalid + * parameter is found. + * \returns showFeatureCount + * \throws QgsBadRequestException + */ + bool showFeatureCountAsBool() const; + + /** Returns SCALE parameter or an empty string if none is defined + * \returns SCALE parameter or an empty string if none is defined + */ + QString scale() const; + + /** Returns SCALE as a double. An exception is raised if an invalid + * parameter is found. + * \returns scale + * \throws QgsBadRequestException + */ + double scaleAsDouble() const; + + /** Returns BOXSPACE parameter or an empty string if not defined. + * \returns BOXSPACE parameter or an empty string if not defined. + */ + QString boxSpace() const; + + /** Returns BOXSPACE as a double or its default value if not defined. + * An exception is raised if an invalid parameter is found. + * \returns boxSpace + * \throws QgsBadRequestException + */ + double boxSpaceAsDouble() const; + + /** Returns LAYERSPACE parameter or an empty string if not defined. + * \returns LAYERSPACE parameter or an empty string if not defined. + */ + QString layerSpace() const; + + /** Returns LAYERSPACE as a double or its default value if not defined. + * An exception is raised if an invalid parameter is found. + * \returns layerSpace + * \throws QgsBadRequestException + */ + double layerSpaceAsDouble() const; + + /** Returns LAYERTITLESPACE parameter or an empty string if not defined. + * \returns LAYERTITLESPACE parameter or an empty string if not defined. + */ + QString layerTitleSpace() const; + + /** Returns LAYERTITLESPACE as a double. An exception is raised if an invalid + * parameter is found. + * \returns layerTitleSpace + * \throws QgsBadRequestException + */ + double layerTitleSpaceAsDouble() const; + + /** Returns SYMBOLSPACE parameter or an empty string if not defined. + * \returns SYMBOLSPACE parameter or an empty string if not defined. + */ + QString symbolSpace() const; + + /** Returns SYMBOLSPACE as a double or its default value if not defined. + * An exception is raised if an invalid parameter is found. + * \returns symbolSpace + * \throws QgsBadRequestException + */ + double symbolSpaceAsDouble() const; + + /** Returns ICONLABELSPACE parameter or an empty string if not defined. + * \returns ICONLABELSPACE parameter or an empty string if not defined. + */ + QString iconLabelSpace() const; + + /** Returns ICONLABELSPACE as a double or its default value if not + * defined. An exception is raised if an invalid parameter is found. + * \returns iconLabelSpace + * \throws QgsBadRequestException + */ + double iconLabelSpaceAsDouble() const; + + /** Returns SYMBOLWIDTH parameter or an empty string if not defined. + * \returns SYMBOLWIDTH parameter or an empty string if not defined. + */ + QString symbolWidth() const; + + /** Returns SYMBOLWIDTH as a double or its default value if not defined. + * An exception is raised if an invalid parameter is found. + * \returns symbolWidth + * \throws QgsBadRequestException + */ + double symbolWidthAsDouble() const; + + /** Returns SYMBOLHEIGHT parameter or an empty string if not defined. + * \returns SYMBOLHEIGHT parameter or an empty string if not defined. + */ + QString symbolHeight() const; + + /** Returns SYMBOLHEIGHT as a double or its default value if not defined. + * An exception is raised if an invalid parameter is found. + * \returns symbolHeight + * \throws QgsBadRequestException + */ + double symbolHeightAsDouble() const; + + /** Returns the layer font (built thanks to the LAYERFONTFAMILY, + * LAYERFONTSIZE, LAYERFONTBOLD, ... parameters). + * \returns layerFont + */ + QFont layerFont() const; + + /** Returns LAYERFONTFAMILY parameter or an empty string if not defined. + * \returns LAYERFONTFAMILY parameter or an empty string if not defined. + */ + QString layerFontFamily() const; + + /** Returns LAYERFONTBOLD parameter or an empty string if not defined. + * \returns LAYERFONTBOLD parameter or an empty string if not defined. + */ + QString layerFontBold() const; + + /** Returns LAYERFONTBOLD as a boolean or its default value if not + * defined. An exception is raised if an + * invalid parameter is found. + * \returns layerFontBold + * \throws QgsBadRequestException + */ + bool layerFontBoldAsBool() const; + + /** Returns LAYERFONTITALIC parameter or an empty string if not defined. + * \returns LAYERFONTITALIC parameter or an empty string if not defined. + */ + QString layerFontItalic() const; + + /** Returns LAYERFONTITALIC as a boolean or its default value if not + * defined. An exception is raised if an invalid parameter is found. + * \returns layerFontItalic + * \throws QgsBadRequestException + */ + bool layerFontItalicAsBool() const; + + /** Returns LAYERFONTSIZE parameter or an empty string if not defined. + * \returns LAYERFONTSIZE parameter or an empty string if not defined. + */ + QString layerFontSize() const; + + /** Returns LAYERFONTSIZE as a double. An exception is raised if an invalid + * parameter is found. + * \returns layerFontSize + * \throws QgsBadRequestException + */ + double layerFontSizeAsDouble() const; + + /** Returns LAYERFONTCOLOR parameter or an empty string if not defined. + * \returns LAYERFONTCOLOR parameter or an empty string if not defined. + */ + QString layerFontColor() const; + + /** Returns LAYERFONTCOLOR as a color or its defined value if not + * defined. An exception is raised if an invalid parameter is found. + * \returns layerFontColor + * \throws QgsBadRequestException + */ + QColor layerFontColorAsColor() const; + + /** Returns the item font (built thanks to the ITEMFONTFAMILY, + * ITEMFONTSIZE, ITEMFONTBOLD, ... parameters). + * \returns itemFont + */ + QFont itemFont() const; + + /** Returns ITEMFONTFAMILY parameter or an empty string if not defined. + * \returns ITEMFONTFAMILY parameter or an empty string if not defined. + */ + QString itemFontFamily() const; + + /** Returns ITEMFONTBOLD parameter or an empty string if not defined. + * \returns ITEMFONTBOLD parameter or an empty string if not defined. + */ + QString itemFontBold() const; + + /** Returns ITEMFONTBOLD as a boolean or its default value if not + * defined. An exception is raised if an invalid parameter is found. + * \returns itemFontBold + * \throws QgsBadRequestException + */ + bool itemFontBoldAsBool() const; + + /** Returns ITEMFONTITALIC parameter or an empty string if not defined. + * \returns ITEMFONTITALIC parameter or an empty string if not defined. + */ + QString itemFontItalic() const; + + /** Returns ITEMFONTITALIC as a boolean or its default value if not + * defined. An exception is raised if an invalid parameter is found. + * \returns itemFontItalic + * \throws QgsBadRequestException + */ + bool itemFontItalicAsBool() const; + + /** Returns ITEMFONTSIZE parameter or an empty string if not defined. + * \returns ITEMFONTSIZE parameter or an empty string if not defined. + */ + QString itemFontSize() const; + + /** Returns ITEMFONTSIZE as a double. An exception is raised if an + * invalid parameter is found. + * \returns itemFontSize + * \throws QgsBadRequestException + */ + double itemFontSizeAsDouble() const; + + /** Returns ITEMFONTCOLOR parameter or an empty string if not defined. + * \returns ITEMFONTCOLOR parameter or an empty string if not defined. + */ + QString itemFontColor() const; + + /** Returns ITEMFONTCOLOR as a color. An exception is raised if an + * invalid parameter is found. + * \returns itemFontColor + * \throws QgsBadRequestException + */ + QColor itemFontColorAsColor() const; + + /** Returns LAYERTITLE parameter or an empty string if not defined. + * \returns LAYERTITLE parameter or an empty string if not defined. + */ + QString layerTitle() const; + + /** Returns LAYERTITLE as a bool or its default value if not defined. An + * exception is raised if an invalid parameter is found. + * \returns layerTitle + * \throws QgsBadRequestException + */ + bool layerTitleAsBool() const; + + /** Returns legend settings + * \returns legend settings + */ + QgsLegendSettings legendSettings() const; + /** Returns parameters for each highlight layer. * \returns parameters for each highlight layer */ @@ -286,8 +601,12 @@ namespace QgsWms void raiseError( const QString &msg ) const; void initParameters(); QVariant value( ParameterName name ) const; + QVariant defaultValue( ParameterName name ) const; void log( const QString &msg ) const; void save( const Parameter ¶meter ); + double toDouble( ParameterName name ) const; + bool toBool( ParameterName name ) const; + int toInt( ParameterName name ) const; QStringList toStringList( ParameterName name, char delimiter = ',' ) const; QList toIntList( QStringList l, ParameterName name ) const; QList toFloatList( QStringList l, ParameterName name ) const; diff --git a/src/server/services/wms/qgswmsrenderer.cpp b/src/server/services/wms/qgswmsrenderer.cpp index a828afc1adf..35ae01fa0ba 100644 --- a/src/server/services/wms/qgswmsrenderer.cpp +++ b/src/server/services/wms/qgswmsrenderer.cpp @@ -67,6 +67,7 @@ #include "qgspallabeling.h" #include "qgslayerrestorer.h" #include "qgsdxfexport.h" +#include "qgssymbollayerutils.h" #include #include @@ -111,8 +112,6 @@ namespace QgsWms QgsWmsConfigParser *parser ) : mParameters( parameters ) , mOwnsConfigParser( false ) - , mDrawLegendLayerLabel( true ) - , mDrawLegendItemLabel( true ) , mConfigParser( parser ) , mAccessControl( serverIface->accessControls() ) , mSettings( *serverIface->serverSettings() ) @@ -138,290 +137,100 @@ namespace QgsWms QImage *QgsRenderer::getLegendGraphics() { - if ( !mConfigParser ) - { - throw QgsException( QStringLiteral( "No config parser" ) ); - } - if ( !mParameters.contains( QStringLiteral( "LAYER" ) ) && !mParameters.contains( QStringLiteral( "LAYERS" ) ) ) - { + // check parameters + if ( mWmsParameters.allLayersNickname().isEmpty() ) throw QgsBadRequestException( QStringLiteral( "LayerNotSpecified" ), QStringLiteral( "LAYER is mandatory for GetLegendGraphic operation" ) ); - } - if ( !mParameters.contains( QStringLiteral( "FORMAT" ) ) ) - { + + if ( mWmsParameters.format() == QgsWmsParameters::Format::NONE ) throw QgsBadRequestException( QStringLiteral( "FormatNotSpecified" ), QStringLiteral( "FORMAT is mandatory for GetLegendGraphic operation" ) ); - } - bool contentBasedLegend = false; - QgsRectangle contentBasedLegendExtent; - - if ( mParameters.contains( QStringLiteral( "BBOX" ) ) ) - { - contentBasedLegend = true; - - contentBasedLegendExtent = parseBbox( mParameters.value( QStringLiteral( "BBOX" ) ) ); - if ( contentBasedLegendExtent.isEmpty() ) - throw QgsBadRequestException( QStringLiteral( "InvalidParameterValue" ), - QStringLiteral( "Invalid BBOX parameter" ) ); - - if ( mParameters.contains( QStringLiteral( "RULE" ) ) ) - throw QgsBadRequestException( QStringLiteral( "InvalidParameterValue" ), - QStringLiteral( "BBOX parameter cannot be combined with RULE" ) ); - } - - QStringList layersList, stylesList; - - readLayersAndStyles( mParameters, layersList, stylesList ); - - if ( layersList.isEmpty() ) - { - return nullptr; - } - - //scale double scaleDenominator = -1; - QMap::const_iterator scaleIt = mParameters.constFind( QStringLiteral( "SCALE" ) ); - if ( scaleIt != mParameters.constEnd() ) - { - bool conversionSuccess; - double scaleValue = scaleIt.value().toDouble( &conversionSuccess ); - if ( conversionSuccess ) - { - scaleDenominator = scaleValue; - } - } + if ( ! mWmsParameters.scale().isEmpty() ) + scaleDenominator = mWmsParameters.scaleAsDouble(); - QgsCoordinateReferenceSystem dummyCRS; - QStringList layerIds = layerSet( layersList, stylesList, dummyCRS, scaleDenominator ); - if ( layerIds.isEmpty() ) - { - return nullptr; - } + QgsLegendSettings legendSettings = mWmsParameters.legendSettings(); - //get icon size, spaces between legend items and font from config parser - double boxSpace, layerSpace, layerTitleSpace, symbolSpace, iconLabelSpace, symbolWidth, symbolHeight; - QFont layerFont, itemFont; - QColor layerFontColor, itemFontColor; - legendParameters( boxSpace, layerSpace, layerTitleSpace, symbolSpace, - iconLabelSpace, symbolWidth, symbolHeight, layerFont, itemFont, layerFontColor, itemFontColor ); + // get layers + std::unique_ptr restorer; + restorer.reset( new QgsLayerRestorer( mNicknameLayers.values() ) ); - QString rule; - int ruleSymbolWidth = 0, ruleSymbolHeight = 0; - QMap::const_iterator ruleIt = mParameters.constFind( QStringLiteral( "RULE" ) ); - if ( ruleIt != mParameters.constEnd() ) - { - rule = ruleIt.value(); + QList layers; + QList params = mWmsParameters.layersParameters(); - QMap::const_iterator widthIt = mParameters.constFind( QStringLiteral( "WIDTH" ) ); - if ( widthIt != mParameters.constEnd() ) - { - bool conversionSuccess; - double width = widthIt.value().toDouble( &conversionSuccess ); - if ( conversionSuccess ) - { - ruleSymbolWidth = width; - } - } + QString sld = mWmsParameters.sld(); + if ( !sld.isEmpty() ) + layers = sldStylizedLayers( sld ); + else + layers = stylizedLayers( params ); - QMap::const_iterator heightIt = mParameters.constFind( QStringLiteral( "HEIGHT" ) ); - if ( heightIt != mParameters.constEnd() ) - { - bool conversionSuccess; - double width = heightIt.value().toDouble( &conversionSuccess ); - if ( conversionSuccess ) - { - ruleSymbolHeight = width; - } - } - } + removeUnwantedLayers( layers, scaleDenominator ); + std::reverse( layers.begin(), layers.end() ); - // Checks showFeatureCount parameter - bool showFeatureCount = false; - if ( mParameters.contains( QStringLiteral( "SHOWFEATURECOUNT" ) ) ) - showFeatureCount = QVariant( mParameters[ QStringLiteral( "SHOWFEATURECOUNT" )] ).toBool(); + // check permissions + Q_FOREACH ( QgsMapLayer *ml, layers ) + checkLayerReadPermissions( ml ); - // Create the layer tree root + // build layer tree model for legend QgsLayerTree rootGroup; - // Store layers' name to reset them - QMap layerNameMap; - // Create tree layer node for each layer - Q_FOREACH ( const QString &layerId, layerIds ) + std::unique_ptr legendModel; + legendModel.reset( buildLegendTreeModel( layers, scaleDenominator, rootGroup ) ); + + // rendering step + qreal dpmm = dotsPerMm(); + std::unique_ptr image; + std::unique_ptr painter; + + if ( !mWmsParameters.rule().isEmpty() ) { - // get layer - QgsMapLayer *ml = QgsProject::instance()->mapLayer( layerId ); - // create tree layer node - QgsLayerTreeLayer *layer = rootGroup.addLayer( ml ); - // store the layer's name - layerNameMap.insert( layerId, ml->name() ); - // set layer name with layer's title to have it in legend - if ( !ml->title().isEmpty() ) - layer->setName( ml->title() ); - // set show feature count - if ( showFeatureCount ) - layer->setCustomProperty( QStringLiteral( "showFeatureCount" ), showFeatureCount ); - } - QgsLayerTreeModel legendModel( &rootGroup ); + QString rule = mWmsParameters.rule(); + int width = mWmsParameters.widthAsInt(); + int height = mWmsParameters.heightAsInt(); - if ( scaleDenominator > 0 ) - legendModel.setLegendFilterByScale( scaleDenominator ); + image.reset( createImage( width, height, false ) ); + painter.reset( new QPainter( image.get() ) ); + painter->setRenderHint( QPainter::Antialiasing, true ); + painter->scale( dpmm, dpmm ); - QgsMapSettings contentBasedMapSettings; - if ( contentBasedLegend ) - { - HitTest hitTest; - getMapOld( contentBasedMapSettings, &hitTest ); - - Q_FOREACH ( QgsLayerTreeNode *node, rootGroup.children() ) - { - Q_ASSERT( QgsLayerTree::isLayer( node ) ); - QgsLayerTreeLayer *nodeLayer = QgsLayerTree::toLayer( node ); - - QgsVectorLayer *vl = qobject_cast( nodeLayer->layer() ); - if ( !vl || !vl->renderer() ) - continue; - - const SymbolSet &usedSymbols = hitTest[vl]; - QList order; - int i = 0; - Q_FOREACH ( const QgsLegendSymbolItem &legendItem, vl->renderer()->legendSymbolItemsV2() ) - { - if ( usedSymbols.contains( legendItem.legacyRuleKey() ) ) - order.append( i ); - ++i; - } - - // either remove the whole layer or just filter out some items - if ( order.isEmpty() ) - rootGroup.removeChildNode( nodeLayer ); - else - { - QgsMapLayerLegendUtils::setLegendNodeOrder( nodeLayer, order ); - legendModel.refreshLayerLegend( nodeLayer ); - } - } - } - - // find out DPI - QImage *tmpImage = createImage( 1, 1, false ); - if ( !tmpImage ) - return nullptr; - qreal dpmm = tmpImage->dotsPerMeterX() / 1000.0; - delete tmpImage; - - // setup legend configuration - QgsLegendSettings legendSettings; - legendSettings.setTitle( QString() ); - legendSettings.setBoxSpace( boxSpace ); - legendSettings.rstyle( QgsLegendStyle::Subgroup ).setMargin( QgsLegendStyle::Top, layerSpace ); - // TODO: not available: layer title space - legendSettings.rstyle( QgsLegendStyle::Symbol ).setMargin( QgsLegendStyle::Top, symbolSpace ); - legendSettings.rstyle( QgsLegendStyle::SymbolLabel ).setMargin( QgsLegendStyle::Left, iconLabelSpace ); - legendSettings.setSymbolSize( QSizeF( symbolWidth, symbolHeight ) ); - legendSettings.rstyle( QgsLegendStyle::Subgroup ).setFont( layerFont ); - legendSettings.rstyle( QgsLegendStyle::SymbolLabel ).setFont( itemFont ); - // TODO: not available: layer font color - legendSettings.setFontColor( itemFontColor ); - - if ( contentBasedLegend ) - { - legendSettings.setMapScale( contentBasedMapSettings.scale() ); - } - - if ( !rule.isEmpty() ) - { - //create second image with the right dimensions - QImage *paintImage = createImage( ruleSymbolWidth, ruleSymbolHeight, false ); - - //go through the items a second time for painting - QPainter p( paintImage ); - p.setRenderHint( QPainter::Antialiasing, true ); - p.scale( dpmm, dpmm ); - - QgsLayerTreeModelLegendNode *legendNode = _findLegendNodeForRule( &legendModel, rule ); + QgsLayerTreeModelLegendNode *legendNode = _findLegendNodeForRule( legendModel.get(), rule ); if ( legendNode ) { QgsLayerTreeModelLegendNode::ItemContext ctx; - ctx.painter = &p; + ctx.painter = painter.get(); ctx.labelXOffset = 0; ctx.point = QPointF(); - double itemHeight = ruleSymbolHeight / dpmm; + double itemHeight = height / dpmm; legendNode->drawSymbol( legendSettings, &ctx, itemHeight ); - } - - QgsProject::instance()->removeAllMapLayers(); - return paintImage; - } - - QList rootChildren = rootGroup.children(); - Q_FOREACH ( QgsLayerTreeNode *node, rootChildren ) - { - if ( QgsLayerTree::isLayer( node ) ) - { - QgsLayerTreeLayer *nodeLayer = QgsLayerTree::toLayer( node ); - -#ifdef HAVE_SERVER_PYTHON_PLUGINS - if ( !mAccessControl->layerReadPermission( nodeLayer->layer() ) ) - { - throw QgsSecurityException( QStringLiteral( "You are not allowed to access to the layer: " ).arg( nodeLayer->layer()->name() ) ); - } -#endif - - // layer titles - hidden or not - QgsLegendRenderer::setNodeLegendStyle( nodeLayer, mDrawLegendLayerLabel ? QgsLegendStyle::Subgroup : QgsLegendStyle::Hidden ); - - // rule item titles - if ( !mDrawLegendItemLabel ) - { - Q_FOREACH ( QgsLayerTreeModelLegendNode *legendNode, legendModel.layerLegendNodes( nodeLayer ) ) - { - legendNode->setUserLabel( QStringLiteral( " " ) ); // empty string = no override, so let's use one space - } - } - else if ( !mDrawLegendLayerLabel ) - { - Q_FOREACH ( QgsLayerTreeModelLegendNode *legendNode, legendModel.layerLegendNodes( nodeLayer ) ) - { - if ( legendNode->isEmbeddedInParent() ) - legendNode->setEmbeddedInParent( false ); - } - } + painter->end(); } } - - QgsLegendRenderer legendRenderer( &legendModel, legendSettings ); - QSizeF minSize = legendRenderer.minimumSize(); - QSize s( minSize.width() * dpmm, minSize.height() * dpmm ); - - QImage *paintImage = createImage( s.width(), s.height(), false ); - - QPainter p( paintImage ); - p.setRenderHint( QPainter::Antialiasing, true ); - p.scale( dpmm, dpmm ); - - legendRenderer.drawLegend( &p ); - - p.end(); - - // reset layers' name - Q_FOREACH ( const QString &layerId, layerIds ) + else { - QgsMapLayer *ml = QgsProject::instance()->mapLayer( layerId ); - ml->setName( layerNameMap[ layerId ] ); + QgsLegendRenderer legendRendererNew( legendModel.get(), legendSettings ); + + QSizeF minSize = legendRendererNew.minimumSize(); + QSize s( minSize.width() * dpmm, minSize.height() * dpmm ); + + image.reset( createImage( s.width(), s.height(), false ) ); + painter.reset( new QPainter( image.get() ) ); + painter->setRenderHint( QPainter::Antialiasing, true ); + painter->scale( dpmm, dpmm ); + + legendRendererNew.drawLegend( painter.get() ); + painter->end(); } - // clear map layer registry - QgsProject::instance()->removeAllMapLayers(); - return paintImage; + + return image.release(); } - void QgsRenderer::runHitTest( const QgsMapSettings &mapSettings, HitTest &hitTest ) const { QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings ); - Q_FOREACH ( const QString &layerID, mapSettings.layerIds() ) + Q_FOREACH ( const QString &id, mapSettings.layerIds() ) { - QgsVectorLayer *vl = qobject_cast( QgsProject::instance()->mapLayer( layerID ) ); + QgsVectorLayer *vl = qobject_cast( mProject->mapLayer( id ) ); if ( !vl || !vl->renderer() ) continue; @@ -455,113 +264,15 @@ namespace QgsWms if ( moreSymbolsPerFeature ) { Q_FOREACH ( QgsSymbol *s, r->originalSymbolsForFeature( f, context ) ) - usedSymbols.insert( s ); + usedSymbols.insert( QgsSymbolLayerUtils::symbolProperties( s ) ); } else - usedSymbols.insert( r->originalSymbolForFeature( f, context ) ); + usedSymbols.insert( QgsSymbolLayerUtils::symbolProperties( r->originalSymbolForFeature( f, context ) ) ); } r->stopRender( context ); } - void QgsRenderer::legendParameters( double &boxSpace, double &layerSpace, double &layerTitleSpace, - double &symbolSpace, double &iconLabelSpace, double &symbolWidth, double &symbolHeight, - QFont &layerFont, QFont &itemFont, QColor &layerFontColor, QColor &itemFontColor ) - { - //spaces between legend elements - QMap::const_iterator boxSpaceIt = mParameters.constFind( QStringLiteral( "BOXSPACE" ) ); - boxSpace = ( boxSpaceIt == mParameters.constEnd() ) ? mConfigParser->legendBoxSpace() : boxSpaceIt.value().toDouble(); - QMap::const_iterator layerSpaceIt = mParameters.constFind( QStringLiteral( "LAYERSPACE" ) ); - layerSpace = ( layerSpaceIt == mParameters.constEnd() ) ? mConfigParser->legendLayerSpace() : layerSpaceIt.value().toDouble(); - QMap::const_iterator layerTitleSpaceIt = mParameters.constFind( QStringLiteral( "LAYERTITLESPACE" ) ); - layerTitleSpace = ( layerTitleSpaceIt == mParameters.constEnd() ) ? mConfigParser->legendLayerTitleSpace() : layerTitleSpaceIt.value().toDouble(); - QMap::const_iterator symbolSpaceIt = mParameters.constFind( QStringLiteral( "SYMBOLSPACE" ) ); - symbolSpace = ( symbolSpaceIt == mParameters.constEnd() ) ? mConfigParser->legendSymbolSpace() : symbolSpaceIt.value().toDouble(); - QMap::const_iterator iconLabelSpaceIt = mParameters.constFind( QStringLiteral( "ICONLABELSPACE" ) ); - iconLabelSpace = ( iconLabelSpaceIt == mParameters.constEnd() ) ? mConfigParser->legendIconLabelSpace() : iconLabelSpaceIt.value().toDouble(); - QMap::const_iterator symbolWidthIt = mParameters.constFind( QStringLiteral( "SYMBOLWIDTH" ) ); - symbolWidth = ( symbolWidthIt == mParameters.constEnd() ) ? mConfigParser->legendSymbolWidth() : symbolWidthIt.value().toDouble(); - QMap::const_iterator symbolHeightIt = mParameters.constFind( QStringLiteral( "SYMBOLHEIGHT" ) ); - symbolHeight = ( symbolHeightIt == mParameters.constEnd() ) ? mConfigParser->legendSymbolHeight() : symbolHeightIt.value().toDouble(); - - //font properties - layerFont = mConfigParser->legendLayerFont(); - QMap::const_iterator layerFontFamilyIt = mParameters.constFind( QStringLiteral( "LAYERFONTFAMILY" ) ); - if ( layerFontFamilyIt != mParameters.constEnd() ) - { - layerFont.setFamily( layerFontFamilyIt.value() ); - } - QMap::const_iterator layerFontBoldIt = mParameters.constFind( QStringLiteral( "LAYERFONTBOLD" ) ); - if ( layerFontBoldIt != mParameters.constEnd() ) - { - layerFont.setBold( layerFontBoldIt.value().compare( QLatin1String( "TRUE" ), Qt::CaseInsensitive ) == 0 ); - } - QMap::const_iterator layerFontItalicIt = mParameters.constFind( QStringLiteral( "LAYERFONTITALIC" ) ); - if ( layerFontItalicIt != mParameters.constEnd() ) - { - layerFont.setItalic( layerFontItalicIt.value().compare( QLatin1String( "TRUE" ), Qt::CaseInsensitive ) == 0 ); - } - QMap::const_iterator layerFontSizeIt = mParameters.constFind( QStringLiteral( "LAYERFONTSIZE" ) ); - layerFont.setPointSizeF( layerFontSizeIt != mParameters.constEnd() ? layerFontSizeIt.value().toDouble() : layerFont.pointSizeF() ); - QMap::const_iterator layerFontColorIt = mParameters.constFind( QStringLiteral( "LAYERFONTCOLOR" ) ); - if ( layerFontColorIt != mParameters.constEnd() ) - { - layerFontColor.setNamedColor( layerFontColorIt.value() ); - } - else - { - layerFontColor = QColor( 0, 0, 0 ); - } - QMap::const_iterator layerTitleIt = mParameters.constFind( QStringLiteral( "LAYERTITLE" ) ); - if ( layerTitleIt != mParameters.constEnd() ) - { - mDrawLegendLayerLabel = ( layerTitleIt.value().compare( QLatin1String( "TRUE" ), Qt::CaseInsensitive ) == 0 ); - } - else - { - mDrawLegendLayerLabel = true; - } - - - itemFont = mConfigParser->legendItemFont(); - QMap::const_iterator itemFontFamilyIt = mParameters.constFind( QStringLiteral( "ITEMFONTFAMILY" ) ); - if ( itemFontFamilyIt != mParameters.constEnd() ) - { - itemFont.setFamily( itemFontFamilyIt.value() ); - } - QMap::const_iterator itemFontBoldIt = mParameters.constFind( QStringLiteral( "ITEMFONTBOLD" ) ); - if ( itemFontBoldIt != mParameters.constEnd() ) - { - itemFont.setBold( itemFontBoldIt.value().compare( QLatin1String( "TRUE" ), Qt::CaseInsensitive ) == 0 ); - } - QMap::const_iterator itemFontItalicIt = mParameters.constFind( QStringLiteral( "ITEMFONTITALIC" ) ); - if ( itemFontItalicIt != mParameters.constEnd() ) - { - itemFont.setItalic( itemFontItalicIt.value().compare( QLatin1String( "TRUE" ), Qt::CaseInsensitive ) == 0 ); - } - QMap::const_iterator itemFontSizeIt = mParameters.constFind( QStringLiteral( "ITEMFONTSIZE" ) ); - itemFont.setPointSizeF( itemFontSizeIt != mParameters.constEnd() ? itemFontSizeIt.value().toDouble() : itemFont.pointSizeF() ); - QMap::const_iterator itemFontColorIt = mParameters.constFind( QStringLiteral( "ITEMFONTCOLOR" ) ); - if ( itemFontColorIt != mParameters.constEnd() ) - { - itemFontColor.setNamedColor( itemFontColorIt.value() ); - } - else - { - itemFontColor = QColor( 0, 0, 0 ); - } - QMap::const_iterator itemLabelIt = mParameters.constFind( QStringLiteral( "RULELABEL" ) ); - if ( itemLabelIt != mParameters.constEnd() ) - { - mDrawLegendItemLabel = ( itemLabelIt.value().compare( QLatin1String( "TRUE" ), Qt::CaseInsensitive ) == 0 ); - } - else - { - mDrawLegendItemLabel = true; - } - } - - QByteArray *QgsRenderer::getPrint( const QString &formatString ) { QStringList layersList, stylesList, layerIdList; @@ -707,105 +418,6 @@ namespace QgsWms } #endif - QImage *QgsRenderer::getMapOld( HitTest *hitTest ) - { - QgsMapSettings mapSettings; - return getMapOld( mapSettings, hitTest ); - } - - QImage *QgsRenderer::getMapOld( QgsMapSettings &mapSettings, HitTest *hitTest ) - { - if ( !checkMaximumWidthHeight() ) - { - throw QgsBadRequestException( QStringLiteral( "Size error" ), - QStringLiteral( "The requested map size is too large" ) ); - } - QStringList layersList, stylesList, layerIdList; - QImage *image = initializeRendering( layersList, stylesList, layerIdList, mapSettings ); - - QStringList layerSetIds = mapSettings.layerIds(); - - QStringList highlightLayersId = QgsWmsConfigParser::addHighlightLayers( mParameters, layerSetIds ); - - QList layerSet; - Q_FOREACH ( QString layerSetId, layerSetIds ) - { - layerSet.append( QgsProject::instance()->mapLayer( layerSetId ) ); - } - mapSettings.setLayers( layerSet ); - -#ifdef HAVE_SERVER_PYTHON_PLUGINS - Q_FOREACH ( QgsMapLayer *layer, QgsProject::instance()->mapLayers() ) - { - if ( !mAccessControl->layerReadPermission( layer ) ) - { - throw QgsSecurityException( QStringLiteral( "You are not allowed to access to the layer: %1" ).arg( layer->name() ) ); - } - } -#endif - - //scoped pointer to restore all original layer filters (subsetStrings) when pointer goes out of scope - //there's LOTS of potential exit paths here, so we avoid having to restore the filters manually - std::unique_ptr< QgsOWSServerFilterRestorer > filterRestorer( new QgsOWSServerFilterRestorer( mAccessControl ) ); - - applyRequestedLayerFilters( layersList, mapSettings, filterRestorer->originalFilters() ); - -#ifdef HAVE_SERVER_PYTHON_PLUGINS - applyAccessControlLayersFilters( layersList, filterRestorer->originalFilters() ); -#endif - - QStringList selectedLayerIdList = applyFeatureSelections( layersList ); - - QList< QPair< QgsVectorLayer *, QgsFeatureRenderer *> > bkVectorRenderers; - QList< QPair< QgsRasterLayer *, QgsRasterRenderer * > > bkRasterRenderers; - QList< QPair< QgsVectorLayer *, double > > labelTransparencies; - QList< QPair< QgsVectorLayer *, double > > labelBufferTransparencies; - - applyOpacities( layersList, bkVectorRenderers, bkRasterRenderers, labelTransparencies, labelBufferTransparencies ); - - std::unique_ptr painter; - if ( hitTest ) - { - runHitTest( mapSettings, *hitTest ); - painter.reset( new QPainter() ); - } - else - { -#ifdef HAVE_SERVER_PYTHON_PLUGINS - mAccessControl->resolveFilterFeatures( mapSettings.layers() ); -#endif - QgsMapRendererJobProxy renderJob( mSettings.parallelRendering(), mSettings.maxThreads(), mAccessControl ); - renderJob.render( mapSettings, image ); - painter.reset( renderJob.takePainter() ); - } - - if ( mConfigParser ) - { - //draw configuration format specific overlay items - mConfigParser->drawOverlays( painter.get(), image->dotsPerMeterX() / 1000.0 * 25.4, image->width(), image->height() ); - } - - restoreOpacities( bkVectorRenderers, bkRasterRenderers, labelTransparencies, labelBufferTransparencies ); - clearFeatureSelections( selectedLayerIdList ); - QgsWmsConfigParser::removeHighlightLayers( highlightLayersId ); - - if ( !hitTest ) - QgsProject::instance()->removeAllMapLayers(); - - painter->end(); - - //test if width / height ratio of image is the same as the ratio of WIDTH / HEIGHT parameters. If not, the image has to be scaled (required by WMS spec) - int widthParam = mParameters.value( "WIDTH", "0" ).toInt(); - int heightParam = mParameters.value( "HEIGHT", "0" ).toInt(); - if ( widthParam != image->width() || heightParam != image->height() ) - { - //scale image - *image = image->scaled( widthParam, heightParam, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ); - } - - return image; - } - QImage *QgsRenderer::getMap( HitTest *hitTest ) { QgsMapSettings mapSettings; @@ -1405,20 +1017,10 @@ namespace QgsWms bool conversionSuccess; if ( width < 0 ) - { - width = mParameters.value( QStringLiteral( "WIDTH" ), QStringLiteral( "0" ) ).toInt( &conversionSuccess ); - if ( !conversionSuccess ) - width = 0; - } + width = mWmsParameters.widthAsInt(); if ( height < 0 ) - { - height = mParameters.value( QStringLiteral( "HEIGHT" ), QStringLiteral( "0" ) ).toInt( &conversionSuccess ); - if ( !conversionSuccess ) - { - height = 0; - } - } + height = mWmsParameters.heightAsInt(); //Adapt width / height if the aspect ratio does not correspond with the BBOX. //Required by WMS spec. 1.3. @@ -2463,15 +2065,15 @@ namespace QgsWms { //test if maxWidth / maxHeight set and WIDTH / HEIGHT parameter is in the range int wmsMaxWidth = QgsServerProjectUtils::wmsMaxWidth( *mProject ); - int width = mWmsParameters.width(); - if ( wmsMaxWidth != -1 && width != -1 && width > wmsMaxWidth ) + int width = mWmsParameters.widthAsInt(); + if ( wmsMaxWidth != -1 && width > wmsMaxWidth ) { return false; } int wmsMaxHeight = QgsServerProjectUtils::wmsMaxHeight( *mProject ); - int height = mWmsParameters.height(); - if ( wmsMaxHeight != -1 && height != -1 && height > wmsMaxHeight ) + int height = mWmsParameters.heightAsInt(); + if ( wmsMaxHeight != -1 && height > wmsMaxHeight ) { return false; } @@ -3272,8 +2874,8 @@ namespace QgsWms // WIDTH / HEIGHT parameters. If not, the image has to be scaled (required // by WMS spec) QImage *scaledImage = nullptr; - int width = mWmsParameters.width(); - int height = mWmsParameters.height(); + int width = mWmsParameters.widthAsInt(); + int height = mWmsParameters.heightAsInt(); if ( width != image->width() || height != image->height() ) { scaledImage = new QImage( image->scaled( width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) ); @@ -3311,4 +2913,125 @@ namespace QgsWms layers = wantedLayers; } + + QgsLayerTreeModel *QgsRenderer::buildLegendTreeModel( const QList &layers, double scaleDenominator, QgsLayerTree &rootGroup ) + { + // get params + bool showFeatureCount = mWmsParameters.showFeatureCountAsBool(); + bool drawLegendLayerLabel = mWmsParameters.layerTitleAsBool(); + bool drawLegendItemLabel = mWmsParameters.ruleLabelAsBool(); + + bool ruleDefined = false; + if ( !mWmsParameters.rule().isEmpty() ) + ruleDefined = true; + + bool contentBasedLegend = false; + QgsRectangle contentBasedLegendExtent; + if ( ! mWmsParameters.bbox().isEmpty() ) + { + contentBasedLegend = true; + contentBasedLegendExtent = mWmsParameters.bboxAsRectangle(); + if ( contentBasedLegendExtent.isEmpty() ) + throw QgsBadRequestException( QStringLiteral( "InvalidParameterValue" ), + QStringLiteral( "Invalid BBOX parameter" ) ); + + if ( !mWmsParameters.rule().isEmpty() ) + throw QgsBadRequestException( QStringLiteral( "InvalidParameterValue" ), + QStringLiteral( "BBOX parameter cannot be combined with RULE" ) ); + } + + // build layer tree + rootGroup.clear(); + Q_FOREACH ( QgsMapLayer *ml, layers ) + { + QgsLayerTreeLayer *lt = rootGroup.addLayer( ml ); + lt->setCustomProperty( QStringLiteral( "showFeatureCount" ), showFeatureCount ); + + if ( !ml->title().isEmpty() ) + lt->setName( ml->title() ); + } + + // build legend model + QgsLayerTreeModel *legendModel = new QgsLayerTreeModel( &rootGroup ); + if ( scaleDenominator > 0 ) + legendModel->setLegendFilterByScale( scaleDenominator ); + + QgsMapSettings contentBasedMapSettings; + if ( contentBasedLegend ) + { + HitTest hitTest; + getMap( contentBasedMapSettings, &hitTest ); + + Q_FOREACH ( QgsLayerTreeNode *node, rootGroup.children() ) + { + Q_ASSERT( QgsLayerTree::isLayer( node ) ); + QgsLayerTreeLayer *nodeLayer = QgsLayerTree::toLayer( node ); + + QgsVectorLayer *vl = qobject_cast( nodeLayer->layer() ); + if ( !vl || !vl->renderer() ) + continue; + + const SymbolSet &usedSymbols = hitTest[vl]; + QList order; + int i = 0; + Q_FOREACH ( const QgsLegendSymbolItem &legendItem, vl->renderer()->legendSymbolItemsV2() ) + { + QString sProp = QgsSymbolLayerUtils::symbolProperties( legendItem.legacyRuleKey() ); + if ( usedSymbols.contains( sProp ) ) + order.append( i ); + ++i; + } + + // either remove the whole layer or just filter out some items + if ( order.isEmpty() ) + rootGroup.removeChildNode( nodeLayer ); + else + { + QgsMapLayerLegendUtils::setLegendNodeOrder( nodeLayer, order ); + legendModel->refreshLayerLegend( nodeLayer ); + } + } + } + + // if legend is not based on rendering rules + if ( ! ruleDefined ) + { + QList rootChildren = rootGroup.children(); + Q_FOREACH ( QgsLayerTreeNode *node, rootChildren ) + { + if ( QgsLayerTree::isLayer( node ) ) + { + QgsLayerTreeLayer *nodeLayer = QgsLayerTree::toLayer( node ); + + // layer titles - hidden or not + QgsLegendRenderer::setNodeLegendStyle( nodeLayer, drawLegendLayerLabel ? QgsLegendStyle::Subgroup : QgsLegendStyle::Hidden ); + + // rule item titles + if ( !drawLegendItemLabel ) + { + Q_FOREACH ( QgsLayerTreeModelLegendNode *legendNode, legendModel->layerLegendNodes( nodeLayer ) ) + { + legendNode->setUserLabel( QStringLiteral( " " ) ); // empty string = no override, so let's use one space + } + } + else if ( !drawLegendLayerLabel ) + { + Q_FOREACH ( QgsLayerTreeModelLegendNode *legendNode, legendModel->layerLegendNodes( nodeLayer ) ) + { + if ( legendNode->isEmbeddedInParent() ) + legendNode->setEmbeddedInParent( false ); + } + } + } + } + } + + return legendModel; + } + + qreal QgsRenderer::dotsPerMm() const + { + std::unique_ptr tmpImage( createImage( 1, 1, false ) ); + return tmpImage->dotsPerMeterX() / 1000.0; + } } // namespace QgsWms diff --git a/src/server/services/wms/qgswmsrenderer.h b/src/server/services/wms/qgswmsrenderer.h index 274ba6454fc..e3f01764017 100644 --- a/src/server/services/wms/qgswmsrenderer.h +++ b/src/server/services/wms/qgswmsrenderer.h @@ -47,6 +47,8 @@ class QgsSymbol; class QgsSymbol; class QgsAccessControl; class QgsDxfExport; +class QgsLayerTreeModel; +class QgsLayerTree; class QColor; class QFile; @@ -88,19 +90,17 @@ namespace QgsWms of the image object*/ QImage *getLegendGraphics(); - typedef QSet SymbolSet; + typedef QSet SymbolSet; typedef QHash HitTest; /** Returns the map as an image (or a null pointer in case of error). The caller takes ownership of the image object). If an instance to existing hit test structure is passed, instead of rendering it will fill the structure with symbols that would be used for rendering */ QImage *getMap( HitTest *hitTest = nullptr ); - QImage *getMapOld( HitTest *hitTest = nullptr ); /** Identical to getMap( HitTest* hitTest ) and updates the map settings actually used. \since QGIS 3.0 */ QImage *getMap( QgsMapSettings &mapSettings, HitTest *hitTest = nullptr ); - QImage *getMapOld( QgsMapSettings &mapSettings, HitTest *hitTest = nullptr ); /** Returns the map as DXF data \param options: extracted from the FORMAT_OPTIONS parameter @@ -173,6 +173,12 @@ namespace QgsWms // Check layer read permissions void checkLayerReadPermissions( QgsMapLayer *layer ) const; + // Build a layer tree model for legend + QgsLayerTreeModel *buildLegendTreeModel( const QList &layers, double scaleDenominator, QgsLayerTree &rootGroup ); + + // Returns default dots per mm + qreal dotsPerMm() const; + /** Initializes WMS layers and configures rendering. * \param layersList out: list with WMS layer names * \param stylesList out: list with WMS style names @@ -236,10 +242,6 @@ namespace QgsWms //! Record which symbols within one layer would be rendered with the given renderer context void runHitTestLayer( QgsVectorLayer *vl, SymbolSet &usedSymbols, QgsRenderContext &context ) const; - //! Read legend parameter from the request or from the first print composer in the project - void legendParameters( double &boxSpace, double &layerSpace, double &layerTitleSpace, - double &symbolSpace, double &iconLabelSpace, double &symbolWidth, double &symbolHeight, QFont &layerFont, QFont &itemFont, QColor &layerFontColor, QColor &itemFontColor ); - /** Apply filter (subset) strings from the request to the layers. Example: '&FILTER=:"AND property > 100",:"AND bla = 'hallo!'" ' * \param layerList list of layer IDs to filter * \param originalFilters hash of layer ID to original filter string @@ -313,10 +315,6 @@ namespace QgsWms bool mOwnsConfigParser; //delete config parser after request (e.g. sent SLD) - // specify if layer or rule item labels should be drawn in the legend graphic with GetLegendGraphics - bool mDrawLegendLayerLabel; - bool mDrawLegendItemLabel; - //! Map containing the WMS parameters QgsWmsConfigParser *mConfigParser = nullptr; From c1657ac853b3a22d36b0c8bef97eb65cee957dd5 Mon Sep 17 00:00:00 2001 From: Blottiere Paul Date: Thu, 8 Jun 2017 09:55:34 +0100 Subject: [PATCH 2/3] [Server] Add/update tests --- tests/src/python/test_qgsserver_wms.py | 157 ++++++ .../WMS_GetLegendGraphic_ItemFont.png | Bin 0 -> 82642 bytes .../WMS_GetLegendGraphic_LayerFont.png | Bin 0 -> 83722 bytes .../WMS_GetLegendGraphic_LayerSpace.png | Bin 0 -> 74687 bytes .../WMS_GetLegendGraphic_ShowFeatureCount.png | Bin 0 -> 33462 bytes .../WMS_GetLegendGraphic_rule0.png | Bin 0 -> 1309 bytes .../WMS_GetLegendGraphic_rule1.png | Bin 0 -> 1309 bytes .../WMS_GetLegendGraphic_rulelabel_false.png | Bin 0 -> 20690 bytes .../WMS_GetLegendGraphic_test_mask.png | Bin 5341 -> 6603 bytes .../WMS_GetLegendGraphic_Hello_mask.png | Bin 239 -> 259 bytes .../qgis_server/test_project_legend_rule.qgs | 445 ++++++++++++++++++ 11 files changed, 602 insertions(+) create mode 100644 tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_ItemFont/WMS_GetLegendGraphic_ItemFont.png create mode 100644 tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_LayerFont/WMS_GetLegendGraphic_LayerFont.png create mode 100644 tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_LayerSpace/WMS_GetLegendGraphic_LayerSpace.png create mode 100644 tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_ShowFeatureCount/WMS_GetLegendGraphic_ShowFeatureCount.png create mode 100644 tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_rule0/WMS_GetLegendGraphic_rule0.png create mode 100644 tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_rule1/WMS_GetLegendGraphic_rule1.png create mode 100644 tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_rulelabel_false/WMS_GetLegendGraphic_rulelabel_false.png create mode 100644 tests/testdata/qgis_server/test_project_legend_rule.qgs diff --git a/tests/src/python/test_qgsserver_wms.py b/tests/src/python/test_qgsserver_wms.py index 870098ce793..b39151d45dc 100644 --- a/tests/src/python/test_qgsserver_wms.py +++ b/tests/src/python/test_qgsserver_wms.py @@ -1027,6 +1027,63 @@ class TestQgsServerWMS(QgsServerTestBase): self.assertEqual(-1, h.find(b'Content-Type: text/xml; charset=utf-8'), "Header: %s\nResponse:\n%s" % (h, r)) self.assertNotEqual(-1, h.find(b'Content-Type: image/png'), "Header: %s\nResponse:\n%s" % (h, r)) + def test_getLegendGraphics_invalid_parameters(self): + """Test that does return an exception""" + qs = "?" + "&".join(["%s=%s" % i for i in list({ + "MAP": urllib.parse.quote(self.projectPath), + "SERVICE": "WMS", + "VERSION": "1.1.1", + "REQUEST": "GetLegendGraphic", + "LAYER": "Country,Hello,db_point", + "LAYERTITLE": "FALSE", + "FORMAT": "image/png", + "HEIGHT": "500", + "WIDTH": "500", + "RULE": "1", + "BBOX": "-151.7,-38.9,51.0,78.0", + "CRS": "EPSG:4326" + }.items())]) + + r, h = self._result(self._execute_request(qs)) + err = b"BBOX parameter cannot be combined with RULE" in r + self.assertTrue(err) + + def test_wms_GetLegendGraphic_LayerSpace(self): + qs = "?" + "&".join(["%s=%s" % i for i in list({ + "MAP": urllib.parse.quote(self.projectPath), + "SERVICE": "WMS", + "VERSION": "1.1.1", + "REQUEST": "GetLegendGraphic", + "LAYER": "Country,Hello", + "FORMAT": "image/png", + # "HEIGHT": "500", + # "WIDTH": "500", + "LAYERSPACE": "50.0", + "LAYERTITLE": "TRUE", + "CRS": "EPSG:3857" + }.items())]) + + r, h = self._result(self._execute_request(qs)) + self._img_diff_error(r, h, "WMS_GetLegendGraphic_LayerSpace") + + def test_wms_GetLegendGraphic_ShowFeatureCount(self): + qs = "?" + "&".join(["%s=%s" % i for i in list({ + "MAP": urllib.parse.quote(self.projectPath), + "SERVICE": "WMS", + "VERSION": "1.1.1", + "REQUEST": "GetLegendGraphic", + "LAYER": "Country,Hello", + "FORMAT": "image/png", + # "HEIGHT": "500", + # "WIDTH": "500", + "LAYERTITLE": "TRUE", + "SHOWFEATURECOUNT": "TRUE", + "CRS": "EPSG:3857" + }.items())]) + + r, h = self._result(self._execute_request(qs)) + self._img_diff_error(r, h, "WMS_GetLegendGraphic_ShowFeatureCount") + def test_getLegendGraphics_layertitle(self): """Test that does not return an exception but an image""" parms = { @@ -1059,6 +1116,66 @@ class TestQgsServerWMS(QgsServerTestBase): r, h = self._result(self._execute_request(qs)) self._img_diff_error(r, h, "WMS_GetLegendGraphic_test_layertitle_false", 250, QSize(15, 15)) + def test_getLegendGraphics_rulelabel(self): + """Test that does not return an exception but an image""" + parms = { + 'MAP': self.testdata_path + "test_project.qgs", + 'SERVICE': 'WMS', + 'VERSION': '1.3.0', + 'REQUEST': 'GetLegendGraphic', + 'FORMAT': 'image/png', + 'LAYER': u'testlayer%20èé', + 'RULELABEL': 'TRUE', + } + qs = '?' + '&'.join([u"%s=%s" % (k, v) for k, v in parms.items()]) + r, h = self._result(self._execute_request(qs)) + self._img_diff_error(r, h, "WMS_GetLegendGraphic_test", 250, QSize(15, 15)) + + parms = { + 'MAP': self.testdata_path + "test_project.qgs", + 'SERVICE': 'WMS', + 'VERSION': '1.3.0', + 'REQUEST': 'GetLegendGraphic', + 'FORMAT': 'image/png', + 'LAYER': u'testlayer%20èé', + 'RULELABEL': 'FALSE', + } + qs = '?' + '&'.join([u"%s=%s" % (k, v) for k, v in parms.items()]) + r, h = self._result(self._execute_request(qs)) + self._img_diff_error(r, h, "WMS_GetLegendGraphic_rulelabel_false", 250, QSize(15, 15)) + + def test_getLegendGraphics_rule(self): + """Test that does not return an exception but an image""" + parms = { + 'MAP': self.testdata_path + "test_project_legend_rule.qgs", + 'SERVICE': 'WMS', + 'VERSION': '1.3.0', + 'REQUEST': 'GetLegendGraphic', + 'FORMAT': 'image/png', + 'LAYER': u'testlayer%20èé', + 'WIDTH': '20', + 'HEIGHT': '20', + 'RULE': 'rule0', + } + qs = '?' + '&'.join([u"%s=%s" % (k, v) for k, v in parms.items()]) + r, h = self._result(self._execute_request(qs)) + self._img_diff_error(r, h, "WMS_GetLegendGraphic_rule0", 250, QSize(15, 15)) + + parms = { + 'MAP': self.testdata_path + "test_project_legend_rule.qgs", + 'SERVICE': 'WMS', + 'VERSION': '1.3.0', + 'REQUEST': 'GetLegendGraphic', + 'FORMAT': 'image/png', + 'LAYER': u'testlayer%20èé', + 'WIDTH': '20', + 'HEIGHT': '20', + 'RULE': 'rule1', + } + qs = '?' + '&'.join([u"%s=%s" % (k, v) for k, v in parms.items()]) + r, h = self._result(self._execute_request(qs)) + self._img_diff_error(r, h, "WMS_GetLegendGraphic_rule1", 250, QSize(15, 15)) + def test_wms_GetLegendGraphic_Basic(self): qs = "?" + "&".join(["%s=%s" % i for i in list({ "MAP": urllib.parse.quote(self.projectPath), @@ -1202,6 +1319,46 @@ class TestQgsServerWMS(QgsServerTestBase): r, h = self._result(self._execute_request(qs)) self._img_diff_error(r, h, "WMS_GetLegendGraphic_SymbolSize") + def test_wms_GetLegendGraphic_LayerFont(self): + qs = "?" + "&".join(["%s=%s" % i for i in list({ + "MAP": urllib.parse.quote(self.projectPath), + "SERVICE": "WMS", + "VERSION": "1.1.1", + "REQUEST": "GetLegendGraphic", + "LAYER": "Country,Hello", + "LAYERTITLE": "TRUE", + "LAYERFONTBOLD": "TRUE", + "LAYERFONTITALIC": "TRUE", + "LAYERFONTSIZE": "30", + "FORMAT": "image/png", + "HEIGHT": "500", + "WIDTH": "500", + "CRS": "EPSG:3857" + }.items())]) + + r, h = self._result(self._execute_request(qs)) + self._img_diff_error(r, h, "WMS_GetLegendGraphic_LayerFont") + + def test_wms_GetLegendGraphic_ItemFont(self): + qs = "?" + "&".join(["%s=%s" % i for i in list({ + "MAP": urllib.parse.quote(self.projectPath), + "SERVICE": "WMS", + "VERSION": "1.1.1", + "REQUEST": "GetLegendGraphic", + "LAYER": "Country,Hello", + "LAYERTITLE": "TRUE", + "ITEMFONTBOLD": "TRUE", + "ITEMFONTITALIC": "TRUE", + "ITEMFONTSIZE": "30", + "FORMAT": "image/png", + "HEIGHT": "500", + "WIDTH": "500", + "CRS": "EPSG:3857" + }.items())]) + + r, h = self._result(self._execute_request(qs)) + self._img_diff_error(r, h, "WMS_GetLegendGraphic_ItemFont") + def test_wms_GetLegendGraphic_BBox(self): qs = "?" + "&".join(["%s=%s" % i for i in list({ "MAP": urllib.parse.quote(self.projectPath), diff --git a/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_ItemFont/WMS_GetLegendGraphic_ItemFont.png b/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_ItemFont/WMS_GetLegendGraphic_ItemFont.png new file mode 100644 index 0000000000000000000000000000000000000000..d251a91281249b9e724b21416b55fc2b4967cd68 GIT binary patch literal 82642 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 literal 0 HcmV?d00001 diff --git a/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_LayerFont/WMS_GetLegendGraphic_LayerFont.png b/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_LayerFont/WMS_GetLegendGraphic_LayerFont.png new file mode 100644 index 0000000000000000000000000000000000000000..fe087e8d3c7f62260ebeb79e1b919f6637e65f8e GIT binary patch literal 83722 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 literal 0 HcmV?d00001 diff --git a/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_rule1/WMS_GetLegendGraphic_rule1.png b/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_rule1/WMS_GetLegendGraphic_rule1.png new file mode 100644 index 0000000000000000000000000000000000000000..766053a5a7c62d08d6e9ee21f09e32665ad7a177 GIT binary patch literal 1309 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1SFYWcSQjy&H|6fVxatI5N6c>Yx|FZf#tlX zi(`m|Amb4h>)(w3|NjT7BM*QqA{!9aoSvFmURsLP0>aJ~;O7IvhmRj)>L+0H;lqbz z#YC7H{$06pg=EbumoL|s6E~2TT(f#Lre+p2q0^^NfBW_gF1T{l%IaX(&)Qr8X^HM-0l9xfg(PN2Gf|NdEMD%+^Z0oi*l-??!A2@@kDkp1b)R|ZzL z2M-^iYX-_W+uL#d`4()U2V`S{Wrxpkib-$WvK1(WCBXI`JY?q=(zJ5tuRnj0HGlv4 zt8($Cpu}{DPM{PPn;{x@?b=mSl$Ygh1=rudg`SkR;^Kkv>Q3a8> zcJ11q-#<^?ee&|>zqjw+fBEvo-o{!-QtZ3` z)4(Vd5)!(6?YgwSInW7f)~tcs%mB=im|(&D`9}^P#uVSQY176H8{pzN{fsakHw(M7 eajQp>892><8m?zr=^pU|Imgr0&t;ucLK6VY=Ix>Y literal 0 HcmV?d00001 diff --git a/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_rulelabel_false/WMS_GetLegendGraphic_rulelabel_false.png b/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_rulelabel_false/WMS_GetLegendGraphic_rulelabel_false.png new file mode 100644 index 0000000000000000000000000000000000000000..6221b3bb34ed964b9ade49de3acc07a1d830f5c5 GIT binary patch literal 20690 zcmeHPc}x^n7~kcT1+*ZjK%f*bH6Rv66wuNZFy)36P^tgaXl+15q=uk|Xy6Y-jR$DF zF^WLa5D=p!DWLI+CWpxAzW2S! z+YN;Yao^jjoK*^i!ZtD@{0DsI;4f%`39eZtIWhRK%8W?)72|I-f6A{$z8+O5+!c}G z-zDWJmCF-Ks+I5GzXy)C|C#~Kq|hb<1C(ePNY=QZL{p+=Vn8N0G@~ieGBF^N8=BFS zXqgz0$qmhDO0-N2$mE7*G$mRl24r$WGnx`D69Y22p&3nymWctG+|Z1sM9aj0Om1jK z|38R+`0(M48#iQ%MRqrb4jo#$bm`^Gmu2v*BcrpjvXYaN1;4;eOG`6i4vf>#%@Ffj1;?OU!?%RN8H zF<-(8Vx*rqaborA)yVFWk`j*gfddCnVRr7^xpL*o$B!Rlw5qBqHa2$Kwr!D-kxbV2 z_xD4$prBy=`t=bJ5y0@ZARHbZj){qJcX!{nZy#>+^YdrUoO%BIdA>o$OLTPfu3fvr z!os$0-O4vuU0n?T!hpw1mo7o2yu94s-#;TGBQY^?-n@C+w{M4#-$Fw}H*MOKo12@E zkN^_3MFmApV0zkDphReEAPz$)XO@gwtkVP|LOdIeZlSJ$#-%g`YW zl7Rd7?@ygN6=@F4iWMv3;^NS0Yim1q?i@O7i;s`5sHng#_+o_F+1a~y??#^!RZ&q9 zgo1&I*k^3wYQ~>iMsnrKmB7G2Oziym^O0_4Wo7B<>Ds^-E?ls%usC}3C;(W14<0;t z{`~pu*|YE5xf2x?m6DPoq6?KtlO`ee4lMK?D$dwYAR zI5;=}$%%&qczb)J4j_Qw;9$T)LPBu;;zQ$TF}GG$R#=^8W@bQ6(iMF;SJ4 zmhRcJ2SULog{fZ?5?5=DuH z&7C{f$;k;(p*S!?!N6F&NXHbUaE7tskdh!SC@9F$(GjDlVyGlnuU?%sYnF?P3xh{N z1cNBVSZI(VAece{J$UdSwj*C(UqruQ!v<7IBsHdF?b@|?a#G9H)s=LOxw(G*I<_MS zu|D_)A)GdCT3%irxY)mcKhh2CkOrAB06_5AFp--+K0c>Tox+l8Z*Rv61Az31ck0T@ zN=zR1NffKb#zrhV#DLU6jhQ}uI>3nP+O=yeOZ>oETU)i+Cw+-+hHN3%*1_8-b_{kD z1sy@-EtQmj2=Ky6(BWv2L!3U}AOJ%{L-2wt3+5Qa5Y`!r1`E)q!>mpu83%m&^ywo< zj&Ov6fpIXLTS-K7Y<*<6cvEU_ZpMCyLMr{y=ude6wZ6$4ylCQ099#69Ide$4aeYd( zal9FAd{00moIzBnZ z#P_c$o|!hwfyvP?=d+n$x|JmDEt^>p-p6Y{P2c|3{#Wc!BI=(hH@ zsHE_KbO<*xJ?_vMAWq(`karGBz=aJbgCQ)EGX; zXCPal_$*!Xe*wm1AN8kU+09PivuDrn9kz{)4J)A?aR!VeTHGidiKu68#yV zMC;F$BqSwT5`FqBQ=;|fN)nP1Er~w;l_}Bsb0rB$iIzm4{>qeS{kf8aq(n=iPk&|m WBz0wWhI&Y&5xFQXyejmkyng`Wnh*g1 literal 0 HcmV?d00001 diff --git a/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_test/WMS_GetLegendGraphic_test_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_test/WMS_GetLegendGraphic_test_mask.png index 93818253838830144bce41111514fe9340a9d4bc..e98f66ade83e06b3f60d9ac35cf3752b9f18856b 100644 GIT binary patch literal 6603 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 Ij77-*04)0Xf&c&j literal 5341 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 YP`N3Li+GY~IIlz$WmRO#q)Y?;1FrN>?EnA( diff --git a/tests/testdata/control_images/qgis_server_accesscontrol/WMS_GetLegendGraphic_Hello/WMS_GetLegendGraphic_Hello_mask.png b/tests/testdata/control_images/qgis_server_accesscontrol/WMS_GetLegendGraphic_Hello/WMS_GetLegendGraphic_Hello_mask.png index 0647ca6f5301c5add4d260cbfac860cebc7908da..1e31689f6330c2058535e93203f3f3986e0b1bbc 100644 GIT binary patch literal 259 zcmeAS@N?(olHy`uVBq!ia0vp^-au@{!3HFM7%b@nQk(@Ik;Opy&mhdG|JU{(P;jfK zi(^Q|oVT|fxtJ9N7!HPhDzD%BjN42_g*!C;;KINUk8V`I?^gbNo!O={qLGU5;Omr& z5|1BC+kaf&G+DF*3Cirde1mPg`X|S+ueoXKL{?^yL|FQMTvU$5>H=O_WRu8BF3_k4&KzQ1ZHShB%$)vC6>SsV!mn^?KUbXYb(7)%im2BQv` z(aInOW;ihb)c{2l8(6u+7GFCVFzGpe`JT`Xkzm!{8&nf&|4gwe+X~~ayZv%8SK<9R S3l;$#!r + + QGIS Test Project + + + + + + + + + testlayer20150528120452665 + + + + + + + + degrees + + 8.20202108826836884 + 44.9009031607650968 + 8.20606418507941449 + 44.90195628381741244 + + 0 + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + 0 + + + + + + + + + + + + + + 8.20345930703634352 + 44.90139483904469131 + 8.20354699399348775 + 44.90148252600183554 + + testlayer20150528120452665 + ./testlayer.shp + A test vector layer + A test vector layer with unicode òà + + + + testlayer èé + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + ogr + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ../../../../../.. + + 0 + ../../../../../.. + + 0 + generatedlayout + + + + + + + name + + + + + + + + + + + + + QGIS TestProject + 4 + + 8 + + + meters + m2 + + + true + D + 2 + + + 255 + + + + + true + + + 3452 + 1 + +proj=longlat +datum=WGS84 +no_defs + EPSG:4326 + + + + QGIS dev team + + + + + WGS84 + + true + elpaso@itopen.it + + + 0 + 255 + 255 + 255 + 255 + 255 + 255 + + 90 + + None + Some UTF8 text èòù + + testlayer20150528120452665 + + + + + + 8.20315414376310059 + 44.901236559338642 + 8.204164917965862 + 44.90159838674664172 + + + + testlayer20150528120452665 + + + testlayer20150528120452665 + + + testlayer20150528120452665 + + + + + off + + + 0 + 2 + + + + current_layer + + + + + + + + false + + + false + + Alessandro Pasotti + + false + conditions unknown + true + + + + + + From 7b844837bb6bcfe8d6d4555bcfe3ad15d81ddd19 Mon Sep 17 00:00:00 2001 From: Blottiere Paul Date: Thu, 8 Jun 2017 10:58:34 +0100 Subject: [PATCH 3/3] [Server] Fonts used in GetLegendGraphics tests are bolded and increased --- tests/src/python/test_qgsserver.py | 5 +- tests/src/python/test_qgsserver_wms.py | 49 ++++++++++++++++-- .../WMS_GetLegendGraphic_ItemFont.png | Bin 82642 -> 88219 bytes .../WMS_GetLegendGraphic_ItemFont_mask.png | Bin 0 -> 10297 bytes .../WMS_GetLegendGraphic_LayerFont.png | Bin 83722 -> 88219 bytes .../WMS_GetLegendGraphic_LayerFont_mask.png | Bin 0 -> 10205 bytes .../WMS_GetLegendGraphic_LayerSpace.png | Bin 74687 -> 180778 bytes .../WMS_GetLegendGraphic_LayerSpace_mask.png | Bin 0 -> 10363 bytes .../WMS_GetLegendGraphic_ShowFeatureCount.png | Bin 33462 -> 123804 bytes ...GetLegendGraphic_ShowFeatureCount_mask.png | Bin 0 -> 12866 bytes .../WMS_GetLegendGraphic_rulelabel_false.png | Bin 20690 -> 108588 bytes ..._GetLegendGraphic_rulelabel_false_mask.png | Bin 0 -> 6076 bytes .../WMS_GetLegendGraphic_test.png | Bin 3190 -> 108588 bytes .../WMS_GetLegendGraphic_test_mask.png | Bin 6603 -> 10142 bytes 14 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_ItemFont/WMS_GetLegendGraphic_ItemFont_mask.png create mode 100644 tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_LayerFont/WMS_GetLegendGraphic_LayerFont_mask.png create mode 100644 tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_LayerSpace/WMS_GetLegendGraphic_LayerSpace_mask.png create mode 100644 tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_ShowFeatureCount/WMS_GetLegendGraphic_ShowFeatureCount_mask.png create mode 100644 tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_rulelabel_false/WMS_GetLegendGraphic_rulelabel_false_mask.png diff --git a/tests/src/python/test_qgsserver.py b/tests/src/python/test_qgsserver.py index 649c1ad21b9..d4e022c2aaf 100644 --- a/tests/src/python/test_qgsserver.py +++ b/tests/src/python/test_qgsserver.py @@ -39,7 +39,7 @@ import email from io import StringIO from qgis.server import QgsServer, QgsServerRequest, QgsBufferServerRequest, QgsBufferServerResponse -from qgis.core import QgsRenderChecker, QgsApplication +from qgis.core import QgsRenderChecker, QgsApplication, QgsFontUtils from qgis.testing import unittest from qgis.PyQt.QtCore import QSize from utilities import unitTestDataPath @@ -94,6 +94,9 @@ class QgsServerTestBase(unittest.TestCase): def setUp(self): """Create the server instance""" + self.fontFamily = QgsFontUtils.standardTestFontFamily() + QgsFontUtils.loadStandardTestFonts(['All']) + self.testdata_path = unitTestDataPath('qgis_server') + '/' d = unitTestDataPath('qgis_server_accesscontrol') + '/' diff --git a/tests/src/python/test_qgsserver_wms.py b/tests/src/python/test_qgsserver_wms.py index b39151d45dc..b57d24df876 100644 --- a/tests/src/python/test_qgsserver_wms.py +++ b/tests/src/python/test_qgsserver_wms.py @@ -1059,6 +1059,12 @@ class TestQgsServerWMS(QgsServerTestBase): # "HEIGHT": "500", # "WIDTH": "500", "LAYERSPACE": "50.0", + "LAYERFONTBOLD": "TRUE", + "LAYERFONTSIZE": "30", + "ITEMFONTBOLD": "TRUE", + "ITEMFONTSIZE": "20", + "LAYERFONTFAMILY": self.fontFamily, + "ITEMFONTFAMILY": self.fontFamily, "LAYERTITLE": "TRUE", "CRS": "EPSG:3857" }.items())]) @@ -1077,15 +1083,24 @@ class TestQgsServerWMS(QgsServerTestBase): # "HEIGHT": "500", # "WIDTH": "500", "LAYERTITLE": "TRUE", + "LAYERFONTBOLD": "TRUE", + "LAYERFONTSIZE": "30", + "LAYERFONTFAMILY": self.fontFamily, + "ITEMFONTFAMILY": self.fontFamily, + "ITEMFONTBOLD": "TRUE", + "ITEMFONTSIZE": "20", "SHOWFEATURECOUNT": "TRUE", "CRS": "EPSG:3857" }.items())]) r, h = self._result(self._execute_request(qs)) - self._img_diff_error(r, h, "WMS_GetLegendGraphic_ShowFeatureCount") + self._img_diff_error(r, h, "WMS_GetLegendGraphic_ShowFeatureCount", max_size_diff=QSize(1, 1)) def test_getLegendGraphics_layertitle(self): """Test that does not return an exception but an image""" + + print("TEST FONT FAMILY: ", self.fontFamily) + parms = { 'MAP': self.testdata_path + "test_project.qgs", 'SERVICE': 'WMS', @@ -1095,6 +1110,12 @@ class TestQgsServerWMS(QgsServerTestBase): # 'WIDTH': '20', # optional # 'HEIGHT': '20', # optional 'LAYER': u'testlayer%20èé', + 'LAYERFONTBOLD': 'TRUE', + 'LAYERFONTSIZE': '30', + 'ITEMFONTBOLD': 'TRUE', + 'LAYERFONTFAMILY': self.fontFamily, + 'ITEMFONTFAMILY': self.fontFamily, + 'ITEMFONTSIZE': '20', 'LAYERTITLE': 'TRUE', } qs = '?' + '&'.join([u"%s=%s" % (k, v) for k, v in parms.items()]) @@ -1125,6 +1146,12 @@ class TestQgsServerWMS(QgsServerTestBase): 'REQUEST': 'GetLegendGraphic', 'FORMAT': 'image/png', 'LAYER': u'testlayer%20èé', + 'LAYERFONTBOLD': 'TRUE', + 'LAYERFONTSIZE': '30', + 'LAYERFONTFAMILY': self.fontFamily, + 'ITEMFONTFAMILY': self.fontFamily, + 'ITEMFONTBOLD': 'TRUE', + 'ITEMFONTSIZE': '20', 'RULELABEL': 'TRUE', } qs = '?' + '&'.join([u"%s=%s" % (k, v) for k, v in parms.items()]) @@ -1138,6 +1165,12 @@ class TestQgsServerWMS(QgsServerTestBase): 'REQUEST': 'GetLegendGraphic', 'FORMAT': 'image/png', 'LAYER': u'testlayer%20èé', + 'LAYERFONTBOLD': 'TRUE', + 'LAYERFONTSIZE': '30', + 'ITEMFONTBOLD': 'TRUE', + 'ITEMFONTSIZE': '20', + 'LAYERFONTFAMILY': self.fontFamily, + 'ITEMFONTFAMILY': self.fontFamily, 'RULELABEL': 'FALSE', } qs = '?' + '&'.join([u"%s=%s" % (k, v) for k, v in parms.items()]) @@ -1330,6 +1363,10 @@ class TestQgsServerWMS(QgsServerTestBase): "LAYERFONTBOLD": "TRUE", "LAYERFONTITALIC": "TRUE", "LAYERFONTSIZE": "30", + "ITEMFONTBOLD": "TRUE", + "ITEMFONTSIZE": "20", + "LAYERFONTFAMILY": self.fontFamily, + "ITEMFONTFAMILY": self.fontFamily, "FORMAT": "image/png", "HEIGHT": "500", "WIDTH": "500", @@ -1337,7 +1374,7 @@ class TestQgsServerWMS(QgsServerTestBase): }.items())]) r, h = self._result(self._execute_request(qs)) - self._img_diff_error(r, h, "WMS_GetLegendGraphic_LayerFont") + self._img_diff_error(r, h, "WMS_GetLegendGraphic_LayerFont", max_size_diff=QSize(1, 1)) def test_wms_GetLegendGraphic_ItemFont(self): qs = "?" + "&".join(["%s=%s" % i for i in list({ @@ -1347,9 +1384,13 @@ class TestQgsServerWMS(QgsServerTestBase): "REQUEST": "GetLegendGraphic", "LAYER": "Country,Hello", "LAYERTITLE": "TRUE", + "LAYERFONTBOLD": "TRUE", + "LAYERFONTSIZE": "30", "ITEMFONTBOLD": "TRUE", "ITEMFONTITALIC": "TRUE", - "ITEMFONTSIZE": "30", + "ITEMFONTSIZE": "20", + "LAYERFONTFAMILY": self.fontFamily, + "ITEMFONTFAMILY": self.fontFamily, "FORMAT": "image/png", "HEIGHT": "500", "WIDTH": "500", @@ -1357,7 +1398,7 @@ class TestQgsServerWMS(QgsServerTestBase): }.items())]) r, h = self._result(self._execute_request(qs)) - self._img_diff_error(r, h, "WMS_GetLegendGraphic_ItemFont") + self._img_diff_error(r, h, "WMS_GetLegendGraphic_ItemFont", max_size_diff=QSize(1, 1)) def test_wms_GetLegendGraphic_BBox(self): qs = "?" + "&".join(["%s=%s" % i for i in list({ diff --git a/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_ItemFont/WMS_GetLegendGraphic_ItemFont.png b/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_ItemFont/WMS_GetLegendGraphic_ItemFont.png index d251a91281249b9e724b21416b55fc2b4967cd68..c78799a44a75634d911a5c1abf0b09424ee7532a 100644 GIT binary patch literal 88219 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 literal 82642 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 diff --git a/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_ItemFont/WMS_GetLegendGraphic_ItemFont_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_ItemFont/WMS_GetLegendGraphic_ItemFont_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..2e725500de583ed3014daf6ac7bb4f14aaa3b0c7 GIT binary patch literal 10297 zcmc(FcQ}@B__s932qk;(k-bNhl`S)b?7jC0*?c{c?46MHAbanXO9OvUbcnTeD_ z(l8Pg{%ED4)$mQ?++GsO2Oj*0ach1iPQG4-2Qj@1E~FkGUHWc6c-VcLP?qSa_35Xd z7ZFa=&keOzgapT`Pkgd`sdg9LN*o7^UKWhBoKf6BL#Lu5mzkNOTwbwZ_1@U5(EDF` zag>pgLbvm=wq{9C%oxlben&X z=<2%ZqfJu+-0%*n|i;j>i6J{=QBM@L^?Uk`(b{C~|oUacW7*Oo)?X5M& zo0B9`cXYF#+nnj3qM}N9>?deBniT`EftoPERT zLh1f7tE;B-Eq=rh8XzV-< z))E5+g}ZR6<&BL=4MT@%-4;Dw<90N2bMp`N^(pGpxzF$rhWKVDpNcyE9+f6Y6%$+4}qQCU3CqO z;13^YRByMsZeY>T(dkzX?h}=~IJofgmojUDl# z|CyoOLVrASTuRD}Wpvu!{=SIAUe;s3)%E`PG25EzU+gc+XdXR6xEZQKS(x*t_FT*^ zR@iPN$ul@RJGXa5;E{Ut_xB5X?vWH+d;MH&$v8cM3K*-gdl7v)NeItwYip~!o1nOT*mnG_fH7b6LV`nHQcW3MCTmfl`&Ou=z%jHoYHPYkk=Tcv947tdhEk7C3py7SZ z0n~)NvU0UN^)RidXxj0a`}Wt{q@<)74kg9Kh5c-`qGDoV(Z9!&K1aHySKXVV(DU;0 z68AoQQ*+Q6hW%x9RA@Hf>|g=85f&Ea?B>STK%Lat-yiks1vwp2H0dVhXgqAVpcQ4U zNae`L2$HEkUPD6zotT(7`c-mY<7eBdynLfN{nDf*#$!U`$pJ$H1DqExUQ9K1gkW@a zb>-?!bFi{@l*6_$7}^mD2nZmryt0xyiW9}y*|AMbOpqR#q8?JCS&!2_7NE}dzE^E2 zG)_G#Gi(YU8+$(0xI0}=FDyJ`?N|2QFzAW#BzD&<7OV%9K6Fk+8h+d5FYIt!a?4Wz zF^`?lH*e6C+(+&Ii;fntdgkWlHeO-&Y^2t((Y>R=ZA*9eV{Wd?-(MF0cQtG`?oeHn zyn1~kEBCj>@67r44|N2Yz(C$E0~6C~jL_l}6BF9akxaX7$23Gmjewq>9_HPO##Km?Nv_C%b>HE`F{Y94w|SSUI2nwi)S9K@Fh#dXmM(#pf)9_|ZMi9v)#*IUkY^ z$)J}y8~K9@D3M!b#l@Y)+9lln=kAa6Dnr$;v#&2P+Sk4-*XX0Vm?cp$AvrlWFE6jA zX^w#`=FZ8=aS1gW+(JQXnXSw4>mS7cYuf*8-7d9=e}p{3=;7QYk$J0e0X*{brj?d_=GV07$Lq)&#p z&waS%!=odfrqYm*n~m<Zt(jX`JT21dTw0>m*4Ad>gMhqs$VLnt^KfI zD|9Om6Ro<9WA&Q)*|TSV&d)!7_<#oWG{M3|h?S#JL_-u!i;wv(J9~-qvYjmvOEmLd zO-&8j)s`MXbkDoN4HhmgC*rm)ee3Cg;Vv_TrBDR%FWYqU^xV|KuhAcVUYMkh3yrNi8(awG%D~7tZoay< zX0rt|`LeZ-sP_khsm%GI72VQ~e*2c!uoafa)N{*o` znbwEPLc&{c#rN;; z&o_CM_Z(~-95{XrX8o70STZTa6ff}iVr^}$!mRJ!jsXomw;)5I7MnhrnjopPfq?-{ zocwcLT}&7@TH4w!jylUG1uDd<+wP)-4tE(&GG*gL*f#Fuj9o$a9 zsJOVepeC=M=xA72Soox*QPW0#xKcUzO92-g)N9?hW(^utNMrW)_CAbTTU)5Bs|)*| z^Ow9t8pYL;hTs~j~mGjsX5_;{qQ7pC>m;fl13j7{HCR&3nt1+QTbG%25V{j z@BHM;@Nf@IXq!s(pf?pQ2Qw9BGxaX?trrJPOo2<^RGXeV=4s$8;E{OBwag}6+?c}feWH()glkEd@w2LD( zJ>8DKHfJRd+WS?!SP0pma)vMgxuE@r$L52{Tz%Cx->jD~0rpAks>111KaI=!5@k~|jwaMP?9~dxASZML9Q+Q!)mYl^(9S9UVc6#l;cq`CrCzq$~U{Ja-I=wCHGQa}@lp zZTfZ+FBDvyoj?2yVP|J2J(8-Y>lc(`OZ*6Jt0AYUjQ{G@D_go={1~~LMOun{IgSgB zJ-Q7ur7wkGW||HracF)2bF_BUg(rEqtDV+f=o;N)%91!hBvyZ)gjAX{*=@E%qbR}T zz09*`-;7Rhad8oQ_lP+Sj44|-Ttxu!miPB#>g$DP_iS`^NrqL=4iDS^U7W?7wp1Wg z3%ZIl3#^sQfTZA+>O=?K#6b7XIJ4TBC<1PnGeoYYriP+|*hG)GeYvujbZ!$76Vvna zPay3vH=R#*v@vg?hvTL1WatikE{&1px2PK3-`gX>llJ$2>@fKuz;*$M$xgH~Q;2GT zG{EzlzN?+y(<*s}kD2Mb?<2y(#*@$+Oc?!G?FZGqzA;<2$Y4Ii8)`m|DUe?6LA-EZEOo&ZN1~$0f|FXXg!Bsl zJ84o_XWbSIH7wd&&tj=$VW9^G2Sui%SqQO!Q%Clg?nvMFZWinw%XV;bQu8C3F`toF zQtB#H&*k~p$R=QO$4jS{o~G-e_Ph_`=Zwi5r2AjS#|duVzCEm% z{Vxw@_Qceb#&@||vzJNd)GJXd5lR5@+~j;+?qd)D5m7=ERfTu4EJ+DQ(}doTUc1=WOod~qSM7;0xts|&BDfJ zdo1xl^InDSrOb(a#B&w~^q>z44WLeVotK~7Cnr}54hbQ3=r-kvij1TI=>^;(tR9q* z`*mbwq~&Ch7TfCXuANR3qf*l6Bn%9U_@lMH2WZ{jzQrR*c!GcbT*?*}7JklqKPr@g zf#DsrL;RO7@>9DA3X%8SJv{_y-Q(kNp%D>P1G3QQWe&*LPrpT2SR$J*e+}lnY73Cz zOxEP(vmByvZOHKU^{q5oJDGkZwC&W*xV5$>eg1pf%z)VhT_t9=_p26pZc*ISsVX|K97q4E$A`m#B{FWEImSh2dTd%MD(v*SIJfx^XA`yI_L|)*l z*GdRZZmH+W0W~uN@rFYxg?azM0}yGEzkj>SwZz9ifG#S0l51Z$X$w35c?y?Wf&wsO z*&aK^+D$0&C~3IvUmh&ZatNM8d!@yo@Uco|&bRH)R-;sxm&c>>YHCizK4w#8hS>QU zQJ`QN`=|e;3E1I3eArXuUD{LYFt@z9*;_o*zSb53?*{xr*G%~ez>`G8HE-MxhmK{ z>W*RqFT2(Sk2il{}Gx!Tqf#?>YqzE|EZZ~ldq+nSemi<6U6 zj`>JRN=lbc^Y_8RTpsei&UT}2gDd0LuV00!(_mcRx_$fUBO-cHQ8JKQritvFoV{Q3 zl`5Q9I+OMe9;oZ-DPXUGu*I#=MZBdHbFD2ZE9;#sc|kx;y+mec?z}ZZIp5&cSBNlb zC^u>ukXJ3)`VvR)eb4}+ih`2TX8R%ew>qa+`gbfjl{F5g3~ut8f5E4C?3*CqP^-+; z1&jM((l#zW{wAOT05&}v8`if1HLI4z?^RYS8ymNsoPH)9oIe-`Nj#Lob5p;R2tI(m z>o&TxUS3}6Zp2bOR@6j{N?vDRnP$Tl%SIDb)V{1RyEToUV0{#4Uz68WH>H{3*cb zv+<3qlkz~GN@kQm0{H-LkA*{>N!J|&DPQlZe+}V{8#hw;ZSE&M(v$KhBqAgX|@%i%#3tOe`s|5K29=JbMUpdZgiwTbIBnxHd2bFz~2k0sr^eu3A*^%HmdKnH^cLLXL9hPe+>i5yO6lPbnCVLz1(qA)#*mEMl})e zWGMjA)1OOAc}R(WSaVK)w+pflXYIr&?fFqbFONA?Tas zf2wy0QZ>WjB$f1cylA+GL0MC+91T7VH}^Zf{8uU}xb!xU4!yq)aI?R(<8@h;dHwHX znrSfb`rny1d`G%rpZZQyQ}bxIyp7kKo{sKtD?2dlwOWaWqgjBOnF!^{e7(!fpr9b6 z$HRvY9g1-bfTEE76Sfn_o=cg!Y$BnH@25#rv|+_hUxfjN^5TGuO;Ab(KxzH{F!Jx; zKbMPBhj5DIuWlyVmQg%Q`5Hz1X%txA$o6~p?jb$E`QaDkF}tVo_up_1YhbBP$wqbd z9G0Y{cZPW4sW1};@6kQXjE$R6}Zm#qiz8V#<4Ass3GT*D4rrx@t_KkqF^NNObh#s> z!fu+g>cC1HWsD4^4hu<2wkddJB_|VGS@LRr`;!_R5z(iaiSbKe(ZIm*>AwiZ>6f&? z^!mlK!&CAS?e)Bdi-Zz^3e$qYRC544`Nvdg`uJ&9Ru)q4^~stj}SErN#arF-Ap?l{puvdw-sAPy$_(bknPh3VKFf`)gJP$M;n409tG45C$2FYC-gZLDm^GSCQl(=cNf$m zx77$m^REGROf0Nmc?KzXsI0&%A8-@jo=Eog^xP&OAgIpR^#%9sgGQ0=Pwf{kB9xLj zQOkiIgr=B(pDwOYmY3{h8c58}zP^Z>1L)g7>+x#KTU*awmQEL_QNygy(>}Kv;;@#7 zR@S@r{A4_p{DGC8@5w9lIo&9gznEaz>()6^!a&yD#m2%q{H7*J%gl@c{2GOkc#@ax z+l+eE)&!O#8Q<6azZaI4%DTAlVA2A;B)Xt+u)(CQ2e{b6@b>W$admUEv0GRGF21`v zr*GJu#PJej=Vzu3u$CfVY6@=)1cF>CGmItf&D_`q_yw1 zAsbxE55F5SRbXB){gNM3Rjf)2Tnn3y@ydaipjp0 zBA~X*j9P3bv3u+1gMCr97zjwJz(A@z?FXR=`?NKh?WE}xB7%HbcMo8$ zQ;Dl3G+oH)Bit5HFj&%>{|+hqPWL+CGA^4#q*LeM7f#uDyK&p(ekzK1Li0iJP;l|f zTzzvxL~JY`igH0gUwiOh=MH05W08y~M3?dVcmTIw(r zdlwg1*4J0m_xFz=VBM=AJ?jJhi4F`5(8TvIudD>k%;^5!pCg7wTkDOfI!}C^L?a;Z z5KI*w4^_;kV3z9_rng80^blmqS@TdgcF+}p-B<&<`YO1Pz~1EDFt!IxV0oWYY@}i z%T$fHIQ#i>FQoTAh=TUPLG1ked?a7B?@Xl;a6K0}1qUp!;eoje`n<9$7^b)YT!TNv z{rF-1J|Ur-v|U0(Bz14GC4KYo1zY0!kMZ2~g6sggtE(%7pplW0IZ&JRoyn5!#lihSlbV~JQ4;EXLfW0&XUQ6^34KaYCUWf3(e6>4DhT*=;sXy!>12c1k=oC_~>)rNL zDY*(0{1_S@{?(j_Ltmyu(s>!}#uJDSzCipDDVIz8qRfC6jCBSuA>DVUVy3P(l3y{2 zh={Di^P7)-cv{^Ers`}BG|s}hKPX`pUOqkrSdj*owL5zC&a`*2v2**4>Yam*uPwku z=Kl_x*z4rjle?b)QVzdDSDE4dT>`AI3|Ckz=7WQS>PnS#!MIq7^TK{V_q~}om(fv) z3&h0aWE^Z+9B3ClURYPwY2eZLGir5*d=1w9S;hSKp8E$2 zO%K4>M1Qk4R~M^8Oiir@0froEapm95fhjt`TZb~DqsI~&2@_D)%^BJeEHlAmUF_t z&S^=tWOpp*CS3jT+8J0$i7>0)zkBzDJvJuBqNP>8^wS71QU#Dod)g4)~MveL79lgDw0X<$vqz=4_8%fKsoltb7g0atRS| z_GA2Jljr_NN?+323!;Y)O}^$SkVw21ZvDGS4jXVQ1OqQTGm{b=lysa(fQ#^*9oyM6 zMF=hdH!Z6Tl}u0Kg+uYfsjEMK9@}FqgEG+tEr6Pc8Dd`d(73_5vct zS*mnN!r@(2xx13Hl}|byIO+Us11vArf_n z&tpNont?ljwEKy>_LVO#4OgH z67)(YlLMubwxr|v@J!aZnXF(vg82Bl`U*l3HZ)l6(JE(ID{EYKPUeL{eXtCVzK`B1DIa~6n=T@ z`M{4>#V+q<*hObo*I*bNii(PbtO0TIp#b_&Tw%xhrD59aUNGCbk{p2P@P2Vr?Ly>BU%1~EheF1<&pxk_WS*@e)iwEbIr zPk3#aZr!co6Bk=7jkR|pABG47t8@*rvVrHLTQK`Q`F{) z--X^rw7;|8-hsbx2-ZHKF%H!jOc8h?OEWHFc)i<^gIN!r=nVPqz+*YYfeZv%$`WoZ}v~1OloJyei}U z*_sp{vpaA4ETbjd^w+c=hL^i9S8Tg(e`SRJKpDIO_^O&^{I!3++2``ldEm4>b8Voo zv9Uo(oF_Ex0Ov*CTo6K5V=QFUPct$yR(BV~NPeWJr#}K$psFoG|Gw(R6lfAyC39X< z)G-m52D;+!1|tdR57%NP$r3@a6oLx`Jj%K##m>&|sE7E~m^e)gFuEQX)43-`lsJ{uTo^?y@OL2l`rAFluOO799gW(73XdCYPY4y%B*&EjTNr>HV|i z49WXCyVgN7gjDVW~}D4xF-Y0W4-7Zi5hB2ssgp_ zPwRsN18{IiCUa|Za}`3TYGLn~B}HE>Y;3)dC306t==k~hjR8L*V`9Q0A~1$~W22&S z4%oq*nQnI7_)kyF1Lv_aGz4^JhPuz({oJ{s-$0~(12W2LT7ZffTQ9eV#|63%y)b^N zVrgZS-s}cM2@b80LAV;K#U=}p4yg5^*@uLX;Q}&FOiU~TB@oPJenuCEI-ujdmFZQ8 zVGj5LX(+~So%~C)_pZm{EntgaR8&+rySsO{2i=6dz(E~6XgACLi;6^?7MpAL88CF( zYC{VgqGDrF+K%e6Zz!aZvA>Wrb8}|nA7#CFOY3IqBYJJzy0RsaXOaK?XPN*fV&Z^3 zyoYlO)jrn<%4WSzvjms5URr2=NR;42(-SzoW?*P|bUNoGB=$nZ4s|F^PQ6IW`}Yq5 pfx#x&r3_)0PSfp8U(Rs_pMqu5&%jS>|_K~XWWiy<$T#Hg_Z8=$fG zf)GW~s3^wRyC$|6TWrxt(f7xF%o}F*l&{?K-S2!qz0B^Jo!y-?XLojXcJ_Y;?YM2% z&P#P}XlUr#xZQwV`1c>+!Aq{Vi-nX_%)&Y#P)JD~yyS|zSV&35EUW_pg_P96ORl(! zg_Kmx!a5+(q3!i?>eQ(xpM0|E*J-Dnw#61(=**mGx=7u^d8OnRzxc%`pL}B2G;-v~ zl~!8GWJ>b6=bpRZf(s-WfFJ(whbNwRqRFgo@_`2)c<{jo4b3H%SivuDpX#B-vVQuUdP zynDl9l21ML)VJSqCVigYGRrK}qeqW%G3zDP+qAAkJu+i$;Ziug)%q8U1M zn`|m6`Rc2$UViyy&sP7!JWeG!IR!c=S|u%MOJ#FONg1QUGtWGOT3|S}?6S))w%B4O zv%1NguRkYRb=y|E)Uww*|NZZOUwrXJ-@`tA`uI%AiN1z))>%go(g9SWci(;Yv(G*Q zZP7&+?b)+u`}XbAi-f0MpgVT#*sE7BQ#L1>DHW1mfBiLW`|`^#J9q9(+ZJDZ@hDoG z%FI;Yr%jvYJN$zm{2;yH!3Q7gOJTrBFU2Hv(n%+6xZ#EiEUIZMNBF!h{Jk zX3R*Zu=2_)>w>`Rt+$>pk`qlAoHAv~&wu`NtN`uWwbNCg&a-s7;f5P#&6=h0+Y;Q6 z*_n$jx=1r6zyk*kOfMK6Y3{h=j-*mAz4X$cL4(W-@b&)q$3JEmNFwt2=bw8Dyjp{w z6HQ9}`OkmOGYYP<$|_Gh@r0CWOF*`i3>h-Szb&j}DO})-XPoz?7^tJA&OiVB1s7b< z<41EC=O2Ca(I_2EtG)JUU{Wkw{8X}+El-) z%8AAdvfFOE@zzZ(DM_Siuf6tq?6Jps_wJp7R(p@qB|T|WD5IZ^jg7vpF=NJfQs{$h z4%~CkJ$&?+Tyn_@E3DvgqJ!D~`|ocsJ9OxPvT5qgiFVjwhZ$-iiB9vgpZ#q3@ZtUX z^@}3(@893lSnJ7*8ON^$qI}7d`O9Da(lF~UfB6e<(Ue64V3g9BtaPyX8Z@*>jT7KC z*Id(}ky9SpEw|iaNRhwo2M;#X@}M!PF+Z9bS&B2f8EPbV+;K;PNs=v3 zk6F7p8CJFE6z-XlC&w%kuDRx#*Is+g6g>X;#v(qD5@9|O=d_k zJ^B3Z-MjnD+RaIm68QC>|NO`Ft!vk=2OMyKH(m+a#EBCH7QlSd*s0`Ec|fO5o!Ax9 zW&P`CF@n)n;{a!(VPiE#NN&9G#y&IT{PUmx^pBE6s-a=kjvp~Yg*yU#xf;kx(@{Kg z=@4IPinxG~XLx_(jW;Uf%^GX0pw?@G!NQaZ@p#cki=HxGegdkPd@1% zZLq-xKC^an(#Dmjlz7(b&L>S+rj*wcA#%bACtzdM)KXw$!g}F_7ucaR_@+{x=0U?T z&(I;c@WKoGOme8ykE0B|ef#!};@49I6Bbi|-)S=iNgj37QPIVY$MiWl z1v(E}be|zfGrjW4E5jzXZqlB6?upr6=hQl!Hsh2bCD9_@(J(3v&p-cs9&R!YdF3%$ zuTh^No(FBoC71Ngc=p+6eI{E}>}H#MRz{;njWU@vpG-3Qc%7fFqCYaVClw)|4I0mp zVZ(-*BGHYKZMWUl`!?%>?3G|>XJlf-Naq7@y6L8-UKZg7Cns7|lcm!4-g{3IM13){ zUTA>ttS(ifaH1U+=Ly4il6Zln_j9YQw(_N}xZ(;^ie(g&x5vbU#on(LMApwY-+c3k z5hH%|qaOu)v<*WIWyn+8b=O_XL&HEE-JzrbfB3^69)9>?tg(z1Sc81~*&Og&NTwOJ zm`s!sbV<(zHp9|88RZ>j5?|`fGtcz&Lrz%nGV&Y0r0^6IoS}v?%%|M#x6lQW55z{r1~0h4uasJG6iM+usbq zV~;)7W1{4ihZag9*_>!hw+w|!G27r8$4bXk*OroTDM1_Xd}np%)ke*W=&r{hha94D zJUn^wg{C%yqREDQV_z7uA)-fi$aHNrVdIHq3!SO4{(ttyUMQUx`^Am6=lMg@q z5a}5^c5HY=W02QqP;Dt&(?HYCI8Dcz%PzZ2W)rM!3>)Hud)#ryF$+l53{e7?3Ltqp zSSh6N-p8X2&pv_{5CKjI;ybGc7|CxNKr0$cN@A$KxB%4$q0z;)Ya%*|epC{y%c33Y zBLh@{-a|mAKoA2lXHuhwF-oejbt1PSDd9E>6Jr3D;kC`;)ALSeGB2P-dYq6GJqn(L zZ1Qz2nDEV0lS4&?lo%FOKZ)+?&+#Xnt;|2X`aL6^$z;F$68)?|=V$D1r}viWZ#il$~CwuEpP$U~-~oUeoE<%F|kv5+aX0{`lj8 z%PcqWv5$t9WiW`3EBW3Jh8d}a^Rk>x!@MR%_1Q=)vu$feBnGG1JRqm4E~%fTqe0UAzCXsx2Wm&91I_uhNUiNQx6c?4@cF(|Q}=;+B6uTyJ6dp*l(2(jF!cW#@$SlCQS-YG1zD? zDl)OzaMsKOA&io$-OPxT=*|#ix{`TaNU<{_aJ2wp)v(V(WWV43_P62Os;0~qF}e#; zTesYDOPyaT3?0rRV_TyZbEcjB0Y)0)o0w2=rB>1U@zcB;`Gy#5D_J8*|CtCds8=$1 z38^SRQ}MN9IAMy!EK7(9MntnxjTS5^lSK^!3A>DF$_%kg%~h|Wr1mr$a+;JhTO*2! zS~&;eYn)cz=%RVe%z;8mnwjA>SzRF|HTl|_xzUA`G&93%vbsV_YVx%;bE69>X=aAk zWOcPICB5fghLFAW85f|X#I3d^rlq)6Z}k>ZQg3g(oc$_4dZg>2Dz= z<#4Uu$`n#kZ*RPu{uWYF4%h0fOd%!p_QuQUZ`GuP$XmDtRmI7zoPHE#nvw$<-i;|$ z6UH5%Q!a|dvyhMtBm*)hod})95d@Cf4jeep-))~lvv|}xIZ%$@8rRj288e1xB6&s* z4zqCo1&1VjG>X>AktS*theG@fR`};~T%(C9=e zGKUj9mx#Gi6Fn_q#^Ewgyq%-hL;C)koIZW}n4Ee`MsKq%JK#z)b1$!y5FvsS3@H(d zQreB{xj#Ohg5M?|c`4y^L9HAh%_Sv7zT@63bKEk#OO727RD#KsyXUzFkwXuhfg=(h zXD~T96G9GW4J3<=IP}`O@&!QOH(vr_{(PilgVS1)nR6t^Qj$(9p@=ahB~c&@8quv# zXih!#)Fd38Pe4SXl^|^#nnLXKqgDuW+>pL={uFgSvw7%t{)`eQ!7>YGB5>gzXWwZC z-*YB%*$CO|9b##+wDCgCJ$EQ#zVil?8yp#IQic{(JkE^WfB*exKXgNi_vq21Z{NNw zl!(Zfexi))7|n5ThzuGuh^T8qO#lc=@cWR-QDo#;5CAx{&LMT3)2mmn5QL48=-gZi zLnK}XBkLAhY{B_qTC0lybG-S+8*cVD;Nw;dXhUPrFgU%3>6qHqeR|#;|;j#6&-&YZ>U1zwP}PEm~U5;C>5qNtgeMxPJoX%dNDe+6DiLSA;d`ZCfr~B>Q@GnBu9dE7fb}$fS=Pm zh%gB$GiUjFea?Xg9w^15%^=XIFGUU^GeW`s{rejPViyWc4G_oHU@{ygX_;wK5*?8? z*kA))SsCzQhaG0x7n00~%*4Zo5AWBnUlairM62TyH24gGQOsR;-PK_7@u4yhH=%`gPvSSV-|EYJ=={BWTu0M|+x3M7XO z8zu+_NR$%hl;|9+dtzwiNwQS-?c-GukyjVjck5_;7C{;fn1#2u3nOg?EhK&P5mZit z$?{&;C~%0X6_C+yysir7)?05a)DS-I{^A#%JJ{|BPxW6duSw0I7UqR<V4I&AKC0jppt# zB`2vFXrtF(f4!i2fMvM}qQR#gE(#FjsIs5FZ;SihKAhCsr;3KJzZAmpjn zkcu_~9O7LwsTpLQM1wYcN8pGnrg40nOQvjgXElz26Q#tz4@wd|&94#-#gwF9yEBlm zu8S6lz6L)YcqvJ;f_v*H^%|Z=-zdv5LVcP>zV+5yCWoZAe~{^0NN}F?>kp#M*na!% zv0eE}O%7Ldm>f-Q^5n@=r%p8pXv%(Rt#J~i#J>-Up-bz+CBax!{jMQuSJHM5)03y~ z8{ppo5s3YQ5K@|1fig=WR`t3TPmQO82M^Xb0cM5iGtI~Z0wWW1w88Xf1|ixE>^cT5 zn)FhlKMy~UV6^mVilLk+C1_Fxm87^G`A3;KQ>IMuIG784X2^*~4>ux3bVffjn&Cm{ zYi5N^G(ddexMn7WQW`e?uIGdLs@ zrNn%-p(GtZIrmiZlJPBho*Q!a9rLNh3tnSp*stLZhM2MBTgKokk0A)bfIt zi(n!L*ea#j8eq92XaPVG)Cj=nvIZw4G4>ivy6inq2)=C4NV3XiHja`FnZ6m^shNTw zeH1n2NMq1>&}*XwqnT+^f~QMVU6INd;Bj!@iAEEcwH^yeBHDY~ui)T$q6zY0`8__CjT%Q_Ghaay z4N{&8K$i_qLhTqx`INCEh96hJNs(wX*ew-=oWOqj?I%6;08ew$3213j0tTaKbbH5F z>~pXjnx?=GkCvH(*5&te0%h*?%PgLR!0i>fc_@4yQ#MRACfm>co(m&$g6}mYUyJrs zi8cdA7a^Dv!0zoU3OQJp&>M5o31}Ho0urlk|B)rNK<7XE?6bZpeBT-;6UHYA`<$l} za;8n2mPrAX5hp5-W*j2qh6|0!nKfT^RK+whC#8@xO)v`U4n~{7D-eP?0dx0)u9rJb za}p7>Y$*YiPuW;5bgfaC5m>9PQXhlx$dMzXpL6`9N7B!Wx7oTsFbfz%Q(BOp&A{8vslh%*2>Z5OC&8lz9|Y zewkj_h9;{9?0>lV@m=zEStXS^_!)w2Ac>6$zXRP7w$X4)*Eu=ilBFak-2$y;Ie?#Q za7dD7@ByPyMXd~ilLRChW0MLL`K_M=7_Nf*o^C3>j^&96M2fLQbFx-p&S`|*RpxH| z9#P1Q*9IE{ta{2@tHP8HwaS>H-HHR_$B*|qwLC}3n=oNQ*&+g+V#X0>)-aG_9idma zl;m_)Nn$}EB}tsArTio*L1X2N8(XRsc1F!OPdqmr58wn}fC{TAsW_`yjw|rPdK&_{ zvDhXo7al@vC3>IKl8Co?WN+hVGY%(OtV+gRsXSK1HCYrQY*Xb?)TJ;eB{?B!G>)F& zV}O%@&J-9!+#Y-E!68n`Y2^S1kHpOY4n)sSRksVlq#0;ZBPPmp*X&Yjk4OpLVU3Lk z%$PB=R9YT?kwq4rI`z5~FC2D#S-(ZS%rrGd(W*$TrrC5b?miN0jd$jq*EefzCBBbOp29Gf*UF<|TZ>#xtAFs>U|dy@v3(%MmA zSH^*elvGA=p3-O=OkM~It_a?njx97JA{>h$N{BvdfdQU_bKG!058b&5P66Q1L>16y zCaz@RHk~Cm0+6#RWEQznLu zC=;kPM7WWH*xmK{;y?j2njjFUfDcl)yt;5?f4GWLvQU>zk2~Si^Dex6+_>?Gg>JfW zcEm~3GeYAF3_H@7c?1m5-WwF;?dlH@{t7h!UXMKG1?xxn)X5`U5pai-qyXSBn1xb4 z;DMk8Ks+xsWgIt6$P%2p5k90)ihHjY_DAI@z6ZM5Rfk*5c49Uv@wdylC(KLbH4B3P zOhF6@cssDKp>Z^v$J0gQ2blTMv^nJSI`f>0@&qLZD=I=DNdR6m1Fa4LL)<5gz-NHT zKytiKt~{y=&|*>|LCZonavny(H!1`_3#ITKWa?o;!QEVkSmOjV-dRZuDo;un>d>iK zkaOIV=|DTm;7SteVrfGlG<}?uvm)fkFY2}zg23UX!*t19gO^>HdbDFb6mXA{9%+4! z15DAw%Ys}5z>iMNGvk;smR)b(5}zY0%+PaUM+goxk!BVuuuNfQ#xX%Ha?Uu^sLxes zUpS@)triftL|zO_Hff;-^o#>C{nAeb);qe8m3(b08#{KabmRl|XS@RuGeh}WqB)Fq`j{KqkDwurl^n0e4KXPygC0(TG*BrX zef&c0xN+fmBrRzopv9!b7~P{$GJKy|_e!QeeqwT>ht(-w-i)IMDu|e41_+8YtWI*0^s7auLn1@vx7@)e5ehm`0ELRUO&#^}ljicxDjRX3XdXG=f!FqRUO#7gS5KeLHfLp^O{tA=&21lfw+y9QV9 zvBPp&T@y4WFEPb}gZax-4mnu=0uj9`Hk5TO0{iGKoZObDO$|hL{=Ppa_Yev^vj6z> zr)SM>m(=IX{PrC>nANW-g4YaQNUZCOdSTGCHpAi&m!(OQCIuXZcjLjuIdx24Y@TT% zBSws%pf}Dk2@*U8OQ=S!5azrRAs6*jSRp}*vpm)+Eji7j!-kf}XPj=`x?u|BZx`0) z75oxcW@|)IQ6>j)eq-zmhjEyH`8NDenn|Q=gos{J zHm#yy)j7c8h`2!bC=p~&qG7Tf)|?_jrwS>l`kSpLL3Amz*@;?Kq0>Sc?Tc%#We_Tg zGy?}%kzqq>=7EHM6?#cCyxj7uUTVPBJYhH Vdcj8D$0KXpddC4bZ*{=w{|f;MACLe5 literal 83722 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 RcwP@lMnX}%Ow{P@{{Ww^9!CHG literal 0 HcmV?d00001 diff --git a/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_LayerSpace/WMS_GetLegendGraphic_LayerSpace.png b/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_LayerSpace/WMS_GetLegendGraphic_LayerSpace.png index 2153a186a45d44894bbdfdea1d7ab7ca1eb8046c..839d4faa238a3ec9f2b676ebea7e452ac3e35443 100644 GIT binary patch literal 180778 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 tD_Lp#J$cXwWV{~vZv~YLR{|_D4`9J^w literal 74687 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 Kmaceg67)Y&$+fBg literal 0 HcmV?d00001 diff --git a/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_rulelabel_false/WMS_GetLegendGraphic_rulelabel_false.png b/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_rulelabel_false/WMS_GetLegendGraphic_rulelabel_false.png index 6221b3bb34ed964b9ade49de3acc07a1d830f5c5..55dce944e313bc4d4b9eff6280292f7257915f15 100644 GIT binary patch literal 108588 zcmeI52ecJM5{BO+2%;Dl118oiM$8cf@dyT75L7UMipPXtUQtn0%;~6@b67Kq3Svev z$74WOQBhG07%-uL!hSf?+f?<;otZcH`rf7PIbwBBb#?XMJ=NXS)$`8&SJ&-ZwrJg= zrlzK4m(HEK*VNQr1-(b}M*O?&2LIWb|II(JbFZU#{?qLLYS;Z^tC=-5ZECu7>d@og zwKe00v>jYKYt}6I>}LoV0){|CM_{(;v!5Yg2p9rYfPk5^D(FOOf+1iC%tpY>nT-QO zz!0bs1k9XONk>{U3;{#H%$bb=L%zHChinX~d?YmyBCL!hDvm^rH`+*X+(U>@2;@e;DZl7@M~CYwbib?@=8C)=(Gro8`5@g9{VRv}w}|FTAix zlRPrDG|Mpr<^=>^dF7Qi-gv`r>CZp^>?e&*k3eSA^UE*49CzGt{2Q#JbLY-G?zm&{ zQI5=yKmPc<^Uf0m_t;~PEw|iKWY+U!)ik8SI2&#i2E3tHm)V@%efQmQwhSz8yz#~Y z&DobpVc?#B{`vRce}C0gS1pISxn=(G#~Z`9fdqU3q^UuH7Vv8Z{$Z->QuBWj8IhvSMq$n7vgJJW-4?leW z{r5lq_+ztX&7w|8s=K&nzyJO_BZ2XN4)oySi!aWhd{N>NJ89A+&i9vJe)$$H_}dX> z|IsOvCr<{<-+ue8QKLo+Ews?0i!RE)Wv{qY1qF^4T~$e(Gnlr>W{EluJM6GaF1bWx zVgXM-{dAF;KKY+NfA9xga+h6p*@F*0D5RZ#{`rLOh)j|bCr-TPnrqlBzx2{eY>FL2 z^XAPtTi9u*od^S3V1Wf(ejG7+^k_EJW5$g6>SX`~ zM~>q>{P4p+`sgEu$BxR(_FW8tdSS7t#Rem60@x&{pzLKLnfSOum98hczIaOx>iL5lN)6*@FJh&6Hh#mMr@F$ z?xT6!xN)qQv{rFBSZd}vtqkEQS$EJCGiPW!aNt1EBDNb-r%u%kA?LpP?i0);bvG3S z9W{RV;fL$2vyQGbm{Y7dBTjX><(3Op6wGYhy7h}Mz8J(U_?q2w&po(Yw5X$xJ~}8Q zAu}jn^Jg+=kz%Kwda974S0v1EyxM{-N(LR`y#K4V`|?FqCm#s-uoNN=r!2 z(ek6!pD2~Xobgt&KlSCXQPpktN374h!wx$L=4koicnTaX$kaIGz&Wk&Oq*)F54-NV zD-CAHjvs35*s*@&F{?zw>cy?kQzp81@7`EgA)HtD&_fT!T|yr-4_|P>1%zw*JZGG7 zM#qjFx7~JIKT{j=HP>9TU%!5(CkxOi~x;75D?_16IqtExG3 z=dj15UvzQm-FV}TX)^uA7!VBjzrYP2tH{?${6so4%Hg$)dsImNeDlqRO`#QZJ${mw zEn7xs0(iLScX1gMWtfk**=8G8^%`re(Wz4>oM{$=xPbM91-?6Bf`hWFm0c;&b8m)KgEnwmE{6hv=#QuUlo{ zvv-`1z}ku}7#^_|R#?F?Liy*w?qZ&BEc}=*Is+gar&pC zkto)rL3f)g5=Z1{NSr8<&uUR`f;f5;Z2oi|wWWLa?t-U4=(=|8Dtdt=gBVCfr7p>2 z<7h|Zz-{~Ox7StU>UA<5p|1&3km8OZBH~`Np+koX&U{HNKWN(02oJ(_@4ff>Wf{OL zuDGIrh{IW*2U^2;;DHDFJOz%HNUX*oQZf_Hsmz(KiCK=ljNiQNw%bl%#1wD7(+s=)1#_ccj(bVaba`y;HNFD ziPGqwhDXa!W6lVv!(GUJlQ9^m0o7IY_0_P2iWyT$dNkNftzAoSnsuBaS%Y2vG+~c4~qj)P&awHXbpMqJ@}1dekrO=&TKK1yd4u*@a@96uYw8j+}DJDeh@R6bM~V z6gF4Xm?oJOHqA;_5o&kV7;-`uqHP)xg%oU(5K+IcP0ExH{vcOPpD0&4W2a z_GqmRKKNk4?C-MmPD?EDf?X^GCMU&ht`#FqxVGS78N$r}-?@MIn00I| zx1d;~isI!>76@H1Ql~PQ1Y3bGOd#Nr!8n_s{;mi_&TY$fq01=-#h_la7k``42`E%f0!gr=a&w>>v zWD?=Yd2{f9JfT#+M?^*Hf^>$z?bi%`PEZ0D;`kA5Kr8~`OAs7#W4Zi-j%L4!N48I& zJ}##M1Q%S0n8j1+*M%XY;RHvUadAvw$MvL!c?+SGLE z)M2ie;b4onpBGmt$29bag82ML<)8`Lz;`AjV}A)V!1LuRLnus}Hf;oFToONt zh_fMR1CNA0TfpxogajeVH*$nzKj}Bk&rhQD9^2)xj4#9_(HTx=CL*|rOE~2uc0@x! zw`Hm{B{S=DE<6*mtHEU(D1>Bfh$x;WsblvTb2?~fsil@;p{)fL2p!1iLsjN>hLf&0 zIVUS_#9rwE;77WN>e$+d?xQ$R_-xw06ZCWWMKaMP<#RzzC`t0P(@xX1aA=@8xn`g_ z$>BguU*{myRzzQMEsRx_kWk=gags~o;5ZYAq>U$wtb|3o1}-iq_i|5P{iO=tmbi*o zBWMRXUknfKFSHQxK?Tj==Wq#*xNV}n*lGIt(Bd8fIawPb1g1&iXBA(J04VMDW(ld! z)WHOS;R6V(hbiMK}AAOiU(Jkf~}HC?fId0(btha zgqx*Tj44M?#@Ie_?!V7I`v?O^6$Or#^a`ipOfqLdGsJo=`KPBx)(DvMG};KBpf8zy zKB4)7(g@yo^o)(=Pn$lBXZ!TTY)qV^~4Bd9j9$Qoci9FQ|9j?f;OEm z2nl_-v=F?sBiQ^Tr$fSNsNJ3V1SyiBajwgY=4(|aI&S3_bbKtm^wJpbxFS)$j_^c3 zTxrRrf=_W(a%ECCkMK7ReK^C8eoXtWIFU8P2kIi6Lvu*vM@zDJ;f(+IDa3$zWuR|kFJU+fY5uKwUT1d$p7ZvI2?C7{}DmbwPLdWEhY+IdH5fL4j`5F=wm5`}@|4vDk9!%p2Wur$$L5DP=7t>p`ICGW{w;Z2}jk_mU$ZM7W zdm8yEonk?!O0qdaF&#h~jTvGlxNno7Igbh)EopE_R)(ixa~2HVV^daAT*Sa(qI-)R zk?=jtWU-vK=(`6_EQB^^2xO7SLd<6?N%I|u|7)`TWBqoS6ASQXZnW_%Da0`l=Yc2U z{{rWx@-=F186{H8D{PaUK0ZO5aEZcm9@iDdIdb?v@h*I>+E*ivjx%it$%h-C!O$Ni z4c5+$%86Ub(p>&YegppJUCS@-FkFlTHf8td%rvaaUsWVg1~S|CK6gw4}r# zsDsO_88@Wu;IMt;e8XYo2==3{Y%&qNxWb?f#tbBjik|X`Excab%wy-LZC%j5Q4sUO zO-I6G6V})G@iA+Bi=VeoYx4BdPZQqAcc_vV_$*3@SbX4t2ebr{ldmB{NOE$>kRh(i zd;*_LazX!T-Jx^RxGco|1^O;w*-gl2FciTF$%h+(gM8Y@IZJ&sA{zToy#&C!iZoHk zyQamuob>Xs(!p&guAOM?<+EwbgF1u*eDHQUC6kFlMoW4e5|ojDyh(R?7346i*~D;y zPb?G*YHSlLYrGJw9=LLsWxW+Ll}I5XfxWMvWeM%9(>^H2Ll4?|+@Irp1H9NBy(SiuJBp zrjQ|E2+Vs3WHVuh*%t0v6|6aMS>_4prZ-)TMk&JlAm?Ei*tn}xWoMI9CQY3-b-Kv3q#pxAzW2S! z+YN;Yao^jjoK*^i!ZtD@{0DsI;4f%`39eZtIWhRK%8W?)72|I-f6A{$z8+O5+!c}G z-zDWJmCF-Ks+I5GzXy)C|C#~Kq|hb<1C(ePNY=QZL{p+=Vn8N0G@~ieGBF^N8=BFS zXqgz0$qmhDO0-N2$mE7*G$mRl24r$WGnx`D69Y22p&3nymWctG+|Z1sM9aj0Om1jK z|38R+`0(M48#iQ%MRqrb4jo#$bm`^Gmu2v*BcrpjvXYaN1;4;eOG`6i4vf>#%@Ffj1;?OU!?%RN8H zF<-(8Vx*rqaborA)yVFWk`j*gfddCnVRr7^xpL*o$B!Rlw5qBqHa2$Kwr!D-kxbV2 z_xD4$prBy=`t=bJ5y0@ZARHbZj){qJcX!{nZy#>+^YdrUoO%BIdA>o$OLTPfu3fvr z!os$0-O4vuU0n?T!hpw1mo7o2yu94s-#;TGBQY^?-n@C+w{M4#-$Fw}H*MOKo12@E zkN^_3MFmApV0zkDphReEAPz$)XO@gwtkVP|LOdIeZlSJ$#-%g`YW zl7Rd7?@ygN6=@F4iWMv3;^NS0Yim1q?i@O7i;s`5sHng#_+o_F+1a~y??#^!RZ&q9 zgo1&I*k^3wYQ~>iMsnrKmB7G2Oziym^O0_4Wo7B<>Ds^-E?ls%usC}3C;(W14<0;t z{`~pu*|YE5xf2x?m6DPoq6?KtlO`ee4lMK?D$dwYAR zI5;=}$%%&qczb)J4j_Qw;9$T)LPBu;;zQ$TF}GG$R#=^8W@bQ6(iMF;SJ4 zmhRcJ2SULog{fZ?5?5=DuH z&7C{f$;k;(p*S!?!N6F&NXHbUaE7tskdh!SC@9F$(GjDlVyGlnuU?%sYnF?P3xh{N z1cNBVSZI(VAece{J$UdSwj*C(UqruQ!v<7IBsHdF?b@|?a#G9H)s=LOxw(G*I<_MS zu|D_)A)GdCT3%irxY)mcKhh2CkOrAB06_5AFp--+K0c>Tox+l8Z*Rv61Az31ck0T@ zN=zR1NffKb#zrhV#DLU6jhQ}uI>3nP+O=yeOZ>oETU)i+Cw+-+hHN3%*1_8-b_{kD z1sy@-EtQmj2=Ky6(BWv2L!3U}AOJ%{L-2wt3+5Qa5Y`!r1`E)q!>mpu83%m&^ywo< zj&Ov6fpIXLTS-K7Y<*<6cvEU_ZpMCyLMr{y=ude6wZ6$4ylCQ099#69Ide$4aeYd( zal9FAd{00moIzBnZ z#P_c$o|!hwfyvP?=d+n$x|JmDEt^>p-p6Y{P2c|3{#Wc!BI=(hH@ zsHE_KbO<*xJ?_vMAWq(`karGBz=aJbgCQ)EGX; zXCPal_$*!Xe*wm1AN8kU+09PivuDrn9kz{)4J)A?aR!VeTHGidiKu68#yV zMC;F$BqSwT5`FqBQ=;|fN)nP1Er~w;l_}Bsb0rB$iIzm4{>qeS{kf8aq(n=iPk&|m WBz0wWhI&Y&5xFQXyejmkyng`Wnh*g1 diff --git a/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_rulelabel_false/WMS_GetLegendGraphic_rulelabel_false_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_rulelabel_false/WMS_GetLegendGraphic_rulelabel_false_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..65a8f41e5748c7d99ed6caab18d6608f7c3e7759 GIT binary patch literal 6076 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 b8OxVnD$ff3PD+4rJdvuBree9g)tmnTxBLO` literal 0 HcmV?d00001 diff --git a/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_test/WMS_GetLegendGraphic_test.png b/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_test/WMS_GetLegendGraphic_test.png index 4e627b316b521f02bbfb0321f03f6af634ad592f..7deef243e6bc7f7e50e6ed3b196e9c030c517260 100644 GIT binary patch literal 108588 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 Vt&;~Y`61%aO|}?v?MAyy`aeBvb8`Ry literal 3190 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 diff --git a/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_test/WMS_GetLegendGraphic_test_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_test/WMS_GetLegendGraphic_test_mask.png index e98f66ade83e06b3f60d9ac35cf3752b9f18856b..2deb2a636964afb5c9cbf61d5aeb6f6f57747960 100644 GIT binary patch literal 10142 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 s($w-mUpa*Yy`nF#A+krZ_ef?WdnZNr`#jG- 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 Ij77-*04)0Xf&c&j