Skip to content
Permalink
Browse files
[server] Implement LAYERFONTCOLOR and ITEMFONTCOLORa
 cherry-picking commit dca0fb9.
  • Loading branch information
elpaso committed Apr 17, 2019
1 parent 1fac5a6 commit 25832b34d3d2f50a34354ffb28c9c4e52fbfa3c4
Show file tree
Hide file tree
Showing 13 changed files with 210 additions and 28 deletions.
@@ -75,6 +75,30 @@ Returns style
QColor fontColor() const;
void setFontColor( const QColor &c );

QColor layerFontColor() const;
%Docstring
Returns layer font color, defaults to fontColor()

.. seealso:: :py:func:`setLayerFontColor`

.. seealso:: :py:func:`fontColor`

.. versionadded:: 3.4.7
%End

void setLayerFontColor( const QColor &fontColor );
%Docstring
Sets layer font color to ``fontColor``
Overrides fontColor()

.. seealso:: :py:func:`layerFontColor`

.. seealso:: :py:func:`fontColor`

.. versionadded:: 3.4.7
%End


QSizeF symbolSize() const;
void setSymbolSize( QSizeF s );

@@ -585,9 +585,9 @@ QSizeF QgsLegendRenderer::drawLayerTitleInternal( QgsLayerTreeLayer *nodeLayer,
double y = point.y();

if ( context && context->painter() )
context->painter()->setPen( mSettings.fontColor() );
context->painter()->setPen( mSettings.layerFontColor() );
else if ( painter )
painter->setPen( mSettings.fontColor() );
painter->setPen( mSettings.layerFontColor() );

QFont layerFont = mSettings.style( nodeLegendStyle( nodeLayer ) ).font();

@@ -88,6 +88,24 @@ class CORE_EXPORT QgsLegendSettings
QColor fontColor() const {return mFontColor;}
void setFontColor( const QColor &c ) {mFontColor = c;}

/**
* Returns layer font color, defaults to fontColor()
* \see setLayerFontColor()
* \see fontColor()
* \since QGIS 3.4.7
*/
QColor layerFontColor() const {return mLayerFontColor.isValid() ? mLayerFontColor : fontColor() ;}

/**
* Sets layer font color to \a fontColor
* Overrides fontColor()
* \see layerFontColor()
* \see fontColor()
* \since QGIS 3.4.7
*/
void setLayerFontColor( const QColor &fontColor ) {mLayerFontColor = fontColor;}


QSizeF symbolSize() const {return mSymbolSize;}
void setSymbolSize( QSizeF s ) {mSymbolSize = s;}

@@ -306,6 +324,9 @@ class CORE_EXPORT QgsLegendSettings

//! DPI to be used when rendering legend
int mDpi = 96;

//! Font color for layers, overrides font color
QColor mLayerFontColor;
};


@@ -1099,6 +1099,16 @@ namespace QgsWms
return mWmsParameters[ QgsWmsParameter::ITEMFONTSIZE ].toDouble();
}

QString QgsWmsParameters::itemFontColor() const
{
return mWmsParameters[ QgsWmsParameter::ITEMFONTCOLOR ].toString();
}

QColor QgsWmsParameters::itemFontColorAsColor() const
{
return mWmsParameters[ QgsWmsParameter::ITEMFONTCOLOR ].toColor();
}

QFont QgsWmsParameters::layerFont() const
{
QFont font;
@@ -1153,6 +1163,18 @@ namespace QgsWms
settings.rstyle( QgsLegendStyle::Style::Subgroup ).setMargin( QgsLegendStyle::Side::Bottom, layerTitleSpaceAsDouble() );
settings.rstyle( QgsLegendStyle::Style::Subgroup ).setFont( layerFont() );

if ( !itemFontColor().isEmpty() )
{
settings.setFontColor( itemFontColorAsColor() );
}

// Ok, this is tricky: because QgsLegendSettings's layerFontColor was added to the API after
// fontColor, to fix regressions #21871 and #21870 and the previous behavior was to use fontColor
// for the whole legend we need to preserve that behavior.
// But, the 2.18 server parameters ITEMFONTCOLOR did not have effect on the layer titles too, so
// we set explicitly layerFontColor to black if it's not overridden by LAYERFONTCOLOR argument.
settings.setLayerFontColor( layerFontColor().isEmpty() ? QColor( Qt::black ) : layerFontColorAsColor() );

settings.rstyle( QgsLegendStyle::Style::SymbolLabel ).setFont( itemFont() );
settings.rstyle( QgsLegendStyle::Style::Symbol ).setMargin( QgsLegendStyle::Side::Top, symbolSpaceAsDouble() );
settings.rstyle( QgsLegendStyle::Style::SymbolLabel ).setMargin( QgsLegendStyle::Side::Left, iconLabelSpaceAsDouble() );
@@ -186,7 +186,7 @@ namespace QgsWms
/**
* Default destructor for QgsWmsParameter.
*/
virtual ~QgsWmsParameter() = default;
virtual ~QgsWmsParameter() override = default;

/**
* Returns true if the parameter is valid, false otherwise.
@@ -335,7 +335,7 @@ namespace QgsWms
*/
QgsWmsParameters();

virtual ~QgsWmsParameters() = default;
virtual ~QgsWmsParameters() override = default;

/**
* Dumps parameters.
@@ -62,27 +62,6 @@ def test_getLegendGraphics(self):
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),
@@ -107,6 +86,27 @@ def test_wms_GetLegendGraphic_LayerSpace(self):
r, h = self._result(self._execute_request(qs))
self._img_diff_error(r, h, "WMS_GetLegendGraphic_LayerSpace", max_size_diff=QSize(1, 1))

def test_wms_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_LayerTitleSpace(self):
qs = "?" + "&".join(["%s=%s" % i for i in list({
"MAP": urllib.parse.quote(self.projectPath),
@@ -155,7 +155,7 @@ def test_wms_GetLegendGraphic_ShowFeatureCount(self):
r, h = self._result(self._execute_request(qs))
self._img_diff_error(r, h, "WMS_GetLegendGraphic_ShowFeatureCount", max_size_diff=QSize(1, 1))

def test_getLegendGraphics_layertitle(self):
def test_wms_getLegendGraphics_layertitle(self):
"""Test that does not return an exception but an image"""

print("TEST FONT FAMILY: ", self.fontFamily)
@@ -196,7 +196,7 @@ def test_getLegendGraphics_layertitle(self):
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):
def test_wms_getLegendGraphics_rulelabel(self):
"""Test that does not return an exception but an image"""
parms = {
'MAP': self.testdata_path + "test_project.qgs",
@@ -236,7 +236,7 @@ def test_getLegendGraphics_rulelabel(self):
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):
def test_wms_getLegendGraphics_rule(self):
"""Test that does not return an exception but an image"""
parms = {
'MAP': self.testdata_path + "test_project_legend_rule.qgs",
@@ -691,6 +691,121 @@ def test_wms_GetLegendGraphic_ScaleSymbol_Max(self):
r, h = self._result(self._execute_request(qs))
self._img_diff_error(r, h, "WMS_GetLegendGraphic_ScaleSymbol_Max", max_size_diff=QSize(15, 15))

def test_wms_GetLegendGraphic_ScaleSymbol_DefaultMapUnitsPerMillimeter(self):
# map units per mm on 1:20000000 with SRCHEIGHT=598&SRCWIDTH=1640&BBOX=16.5,-69.7,73.3,86.1 would be around what is set as default: 0.359 map units per mm
qs = "?" + "&".join(["%s=%s" % i for i in list({
"MAP": self.testdata_path + 'test_project_scaledsymbols.qgs',
"SERVICE": "WMS",
"REQUEST": "GetLegendGraphic",
"LAYER": "testlayer",
"FORMAT": "image/png",
"CRS": "EPSG:4326"
}.items())])

r, h = self._result(self._execute_request(qs))
self._img_diff_error(r, h, "WMS_GetLegendGraphic_ScaleSymbol_DefaultMapUnitsPerMillimeter", max_size_diff=QSize(15, 15))

def test_wms_GetLegendGraphic_ScaleSymbol_Scaled_2056(self):
# 1:1000 scale on an EPSG:2056 calculating DPI that is around 96
qs = "?" + "&".join(["%s=%s" % i for i in list({
"MAP": self.testdata_path + 'test_project_scaledsymbols_2056.qgs',
"SERVICE": "WMS",
"REQUEST": "GetLegendGraphic",
"LAYER": "testlayer_2056",
"FORMAT": "image/png",
"SRCHEIGHT": "600",
"SRCWIDTH": "1500",
"BBOX": "2662610.7,1268841.8,2663010.5,1269000.05",
"CRS": "EPSG:2056"
}.items())])

r, h = self._result(self._execute_request(qs))
self._img_diff_error(r, h, "WMS_GetLegendGraphic_ScaleSymbol_Scaled_2056", max_size_diff=QSize(15, 15))

def test_wms_GetLegendGraphic_ScaleSymbol_DefaultScale_2056(self):
# 1:1000 as default value - it's not exactly the same result than passing the bbox and size because of exact DPI 96 (default)
qs = "?" + "&".join(["%s=%s" % i for i in list({
"MAP": self.testdata_path + 'test_project_scaledsymbols_2056.qgs',
"SERVICE": "WMS",
"REQUEST": "GetLegendGraphic",
"LAYER": "testlayer_2056",
"FORMAT": "image/png",
"CRS": "EPSG:2056"
}.items())])

r, h = self._result(self._execute_request(qs))
self._img_diff_error(r, h, "WMS_GetLegendGraphic_ScaleSymbol_DefaultScale_2056", max_size_diff=QSize(15, 15))

def test_wms_GetLegendGraphic_LAYERFONTCOLOR(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",
"CRS": "EPSG:3857",
"LAYERFONTCOLOR": "red"
}.items())])

r, h = self._result(self._execute_request(qs))
self._img_diff_error(r, h, "WMS_GetLegendGraphic_LAYERFONTCOLOR", max_size_diff=QSize(10, 2))

def test_wms_GetLegendGraphic_ITEMFONTCOLOR(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",
"CRS": "EPSG:3857",
"ITEMFONTCOLOR": "red",
}.items())])

r, h = self._result(self._execute_request(qs))
self._img_diff_error(r, h, "WMS_GetLegendGraphic_ITEMFONTCOLOR", max_size_diff=QSize(10, 2))

def test_wms_GetLegendGraphic_ITEMFONTCOLOR_and_LAYERFONTCOLOR(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",
"CRS": "EPSG:3857",
"ITEMFONTCOLOR": "red",
"LAYERFONTCOLOR": "blue"
}.items())])

r, h = self._result(self._execute_request(qs))
self._img_diff_error(r, h, "WMS_GetLegendGraphic_ITEMFONTCOLOR_and_LAYERFONTCOLOR", max_size_diff=QSize(10, 2))

def test_wms_GetLegendGraphic_ITEMFONTCOLOR_and_LAYERFONTCOLOR_hex(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",
"CRS": "EPSG:3857",
"ITEMFONTCOLOR": r"%23FF0000",
"LAYERFONTCOLOR": r"%230000FF"
}.items())])

r, h = self._result(self._execute_request(qs))
self._img_diff_error(r, h, "WMS_GetLegendGraphic_ITEMFONTCOLOR_and_LAYERFONTCOLOR", max_size_diff=QSize(10, 2))


if __name__ == '__main__':
unittest.main()
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.

0 comments on commit 25832b3

Please sign in to comment.