Skip to content

Commit

Permalink
Merge pull request #33725 from rldhont/fix-read-sld-textsymbolizer-units
Browse files Browse the repository at this point in the history
[BUGFIX] Read SLD TextSymbolizer set units to pixels
  • Loading branch information
rldhont committed Jan 16, 2020
2 parents fe7085d + dbb53be commit ab9cbe0
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 3 deletions.
Expand Up @@ -171,7 +171,7 @@ Encodes a render unit into an SLD unit of measure string.
.. seealso:: :py:func:`decodeSldUom`
%End

static QgsUnitTypes::RenderUnit decodeSldUom( const QString &str, double *scaleFactor );
static QgsUnitTypes::RenderUnit decodeSldUom( const QString &str, double *scaleFactor = 0 );
%Docstring
Decodes a SLD unit of measure string to a render unit.

Expand Down
16 changes: 16 additions & 0 deletions src/core/qgsvectorlayer.cpp
Expand Up @@ -4473,8 +4473,15 @@ bool QgsVectorLayer::readSldTextSymbolizer( const QDomNode &node, QgsPalLayerSet
return false;
}

QgsUnitTypes::RenderUnit sldUnitSize = QgsUnitTypes::RenderPixels;
if ( textSymbolizerElem.hasAttribute( QStringLiteral( "uom" ) ) )
{
sldUnitSize = QgsSymbolLayerUtils::decodeSldUom( textSymbolizerElem.attribute( QStringLiteral( "uom" ) ) );
}

QString fontFamily = QStringLiteral( "Sans-Serif" );
int fontPointSize = 10;
QgsUnitTypes::RenderUnit fontUnitSize = QgsUnitTypes::RenderPoints;
int fontWeight = -1;
bool fontItalic = false;
bool fontUnderline = false;
Expand All @@ -4501,7 +4508,10 @@ bool QgsVectorLayer::readSldTextSymbolizer( const QDomNode &node, QgsPalLayerSet
bool ok;
int fontSize = it.value().toInt( &ok );
if ( ok )
{
fontPointSize = fontSize;
fontUnitSize = sldUnitSize;
}
}
else if ( it.key() == QLatin1String( "font-weight" ) )
{
Expand All @@ -4520,6 +4530,7 @@ bool QgsVectorLayer::readSldTextSymbolizer( const QDomNode &node, QgsPalLayerSet
font.setUnderline( fontUnderline );
format.setFont( font );
format.setSize( fontPointSize );
format.setSizeUnit( fontUnitSize );

// Fill
QDomElement fillElem = textSymbolizerElem.firstChildElement( QStringLiteral( "Fill" ) );
Expand Down Expand Up @@ -4549,6 +4560,7 @@ bool QgsVectorLayer::readSldTextSymbolizer( const QDomNode &node, QgsPalLayerSet
if ( ok )
{
bufferSettings.setSize( bufferSize );
bufferSettings.setSizeUnit( sldUnitSize );
}
}

Expand Down Expand Up @@ -4584,6 +4596,7 @@ bool QgsVectorLayer::readSldTextSymbolizer( const QDomNode &node, QgsPalLayerSet
if ( ok )
{
settings.xOffset = xOffset;
settings.offsetUnits = sldUnitSize;
}
}
QDomElement displacementYElem = displacementElem.firstChildElement( QStringLiteral( "DisplacementY" ) );
Expand All @@ -4594,6 +4607,7 @@ bool QgsVectorLayer::readSldTextSymbolizer( const QDomNode &node, QgsPalLayerSet
if ( ok )
{
settings.yOffset = yOffset;
settings.offsetUnits = sldUnitSize;
}
}
}
Expand All @@ -4608,6 +4622,7 @@ bool QgsVectorLayer::readSldTextSymbolizer( const QDomNode &node, QgsPalLayerSet
if ( ok )
{
settings.xOffset = xOffset;
settings.offsetUnits = sldUnitSize;
}
}
QDomElement anchorPointYElem = anchorPointElem.firstChildElement( QStringLiteral( "AnchorPointY" ) );
Expand All @@ -4618,6 +4633,7 @@ bool QgsVectorLayer::readSldTextSymbolizer( const QDomNode &node, QgsPalLayerSet
if ( ok )
{
settings.yOffset = yOffset;
settings.offsetUnits = sldUnitSize;
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/core/symbology/qgssymbollayerutils.cpp
Expand Up @@ -640,6 +640,12 @@ QgsUnitTypes::RenderUnit QgsSymbolLayerUtils::decodeSldUom( const QString &str,
*scaleFactor = 304.8; // from feet to meters
return QgsUnitTypes::RenderMapUnits;
}
else if ( str == QLatin1String( "http://www.opengeospatial.org/se/units/pixel" ) )
{
if ( scaleFactor )
*scaleFactor = 1.0; // from pixels to pixels
return QgsUnitTypes::RenderPixels;
}

// pixel is the SLD default uom. The "standardized rendering pixel
// size" is defined to be 0.28mm x 0.28mm (millimeters).
Expand Down
2 changes: 1 addition & 1 deletion src/core/symbology/qgssymbollayerutils.h
Expand Up @@ -191,7 +191,7 @@ class CORE_EXPORT QgsSymbolLayerUtils
* \returns matching render unit
* \see encodeSldUom()
*/
static QgsUnitTypes::RenderUnit decodeSldUom( const QString &str, double *scaleFactor );
static QgsUnitTypes::RenderUnit decodeSldUom( const QString &str, double *scaleFactor = nullptr );

/**
* Returns the size scaled in pixels according to the uom attribute.
Expand Down
2 changes: 2 additions & 0 deletions tests/src/python/test_qgssymbollayer_readsld.py
Expand Up @@ -442,10 +442,12 @@ def testLineOpacity():
self.assertFalse(font.italic())

self.assertEqual(format.size(), 18)
self.assertEqual(format.sizeUnit(), QgsUnitTypes.RenderPixels)

self.assertEqual(settings.placement, QgsPalLayerSettings.OverPoint)
self.assertEqual(settings.xOffset, 1)
self.assertEqual(settings.yOffset, 0)
self.assertEqual(settings.offsetUnits, QgsUnitTypes.RenderPixels)


if __name__ == '__main__':
Expand Down
38 changes: 37 additions & 1 deletion tests/src/python/test_qgssymbollayerutils.py
Expand Up @@ -14,7 +14,8 @@

from qgis.core import (QgsSymbolLayerUtils,
QgsMarkerSymbol,
QgsArrowSymbolLayer)
QgsArrowSymbolLayer,
QgsUnitTypes)
from qgis.PyQt.QtGui import QColor
from qgis.PyQt.QtCore import QSizeF, QPointF
from qgis.testing import unittest, start_app
Expand Down Expand Up @@ -210,6 +211,41 @@ def testSymbolToFromMimeData(self):
self.assertTrue(symbol2 is not None)
self.assertEqual(symbol2.color().name(), symbol.color().name())

def testEncodeSldUom(self):
"""
Test Encodes a SLD unit of measure string to a render unit
"""

# millimeter
encode = None
encode = QgsSymbolLayerUtils.encodeSldUom(QgsUnitTypes.RenderMillimeters)
self.assertTupleEqual(encode, ('', 3.571428571428571))

# mapunits
encode = None
encode = QgsSymbolLayerUtils.encodeSldUom(QgsUnitTypes.RenderMapUnits)
self.assertTupleEqual(encode, ('http://www.opengeospatial.org/se/units/metre', 0.001))

def testDecodeSldUom(self):
"""
Test Decodes a SLD unit of measure string to a render unit
"""

# meter
decode = None
decode = QgsSymbolLayerUtils.decodeSldUom("http://www.opengeospatial.org/se/units/metre")
self.assertEqual(decode, (QgsUnitTypes.RenderMapUnits, 1000.0))

# foot
decode = None
decode = QgsSymbolLayerUtils.decodeSldUom("http://www.opengeospatial.org/se/units/foot")
self.assertEqual(decode, (QgsUnitTypes.RenderMapUnits, 304.8))

# pixel
decode = None
decode = QgsSymbolLayerUtils.decodeSldUom("http://www.opengeospatial.org/se/units/pixel")
self.assertEqual(decode, (QgsUnitTypes.RenderPixels, 1.0))


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

0 comments on commit ab9cbe0

Please sign in to comment.