Skip to content

Commit 1d702d2

Browse files
authoredSep 13, 2017
Merge pull request #5144 from boundlessgeo/Backport_Fix_uom_reading
[bugfix] backport from 3.0 Fix unit of sizes when reading a SLD file (fixes #8978)
2 parents b3a8d6f + 439477a commit 1d702d2

13 files changed

+466
-5
lines changed
 

‎python/core/symbology-ng/qgssymbollayerv2utils.sip

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ class QgsSymbolLayerV2Utils
5757
static QString encodeSldUom( QgsSymbolV2::OutputUnit unit, double *scaleFactor );
5858
static QgsSymbolV2::OutputUnit decodeSldUom( const QString& str, double *scaleFactor );
5959

60+
/** Returns the size scaled in pixels according to the uom attribute.
61+
* \param uom The uom attribute from SLD 1.1 version
62+
* \param size The original size
63+
* \returns the size in pixels
64+
* \since QGIS 3.0
65+
*/
66+
static double sizeInPixelsFromSldUom( const QString &uom, double size );
67+
6068
static QString encodeScaleMethod( QgsSymbolV2::ScaleMethod scaleMethod );
6169
static QgsSymbolV2::ScaleMethod decodeScaleMethod( const QString& str );
6270

‎src/core/symbology-ng/qgsellipsesymbollayerv2.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,10 @@ QgsSymbolLayerV2* QgsEllipseSymbolLayerV2::createFromSld( QDomElement &element )
490490
if ( !QgsSymbolLayerV2Utils::wellKnownMarkerFromSld( graphicElem, name, fillColor, borderColor, borderStyle, borderWidth, size ) )
491491
return nullptr;
492492

493+
const QString uom = element.attribute( QString( "uom" ), "" );
494+
size = QgsSymbolLayerV2Utils::sizeInPixelsFromSldUom( uom, size );
495+
borderWidth = QgsSymbolLayerV2Utils::sizeInPixelsFromSldUom( uom, borderWidth );
496+
493497
double angle = 0.0;
494498
QString angleFunc;
495499
if ( QgsSymbolLayerV2Utils::rotationFromSldElement( graphicElem, angleFunc ) )
@@ -501,6 +505,7 @@ QgsSymbolLayerV2* QgsEllipseSymbolLayerV2::createFromSld( QDomElement &element )
501505
}
502506

503507
QgsEllipseSymbolLayerV2 *m = new QgsEllipseSymbolLayerV2();
508+
m->setOutputUnit( QgsSymbolV2::Pixel );
504509
m->setSymbolName( name );
505510
m->setFillColor( fillColor );
506511
m->setOutlineColor( borderColor );

‎src/core/symbology-ng/qgsfillsymbollayerv2.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,13 @@ QgsSymbolLayerV2* QgsSimpleFillSymbolLayerV2::createFromSld( QDomElement &elemen
390390
QPointF offset;
391391
QgsSymbolLayerV2Utils::displacementFromSldElement( element, offset );
392392

393+
QString uom = element.attribute( QString( "uom" ), "" );
394+
offset.setX( QgsSymbolLayerV2Utils::sizeInPixelsFromSldUom( uom, offset.x() ) );
395+
offset.setY( QgsSymbolLayerV2Utils::sizeInPixelsFromSldUom( uom, offset.y() ) );
396+
borderWidth = QgsSymbolLayerV2Utils::sizeInPixelsFromSldUom( uom, borderWidth );
397+
393398
QgsSimpleFillSymbolLayerV2* sl = new QgsSimpleFillSymbolLayerV2( color, fillStyle, borderColor, borderStyle, borderWidth );
399+
sl->setOutputUnit( QgsSymbolV2::Pixel );
394400
sl->setOffset( offset );
395401
return sl;
396402
}
@@ -2159,6 +2165,10 @@ QgsSymbolLayerV2* QgsSVGFillSymbolLayer::createFromSld( QDomElement &element )
21592165

21602166
QgsSymbolLayerV2Utils::lineFromSld( graphicElem, penStyle, borderColor, borderWidth );
21612167

2168+
QString uom = element.attribute( QString( "uom" ), "" );
2169+
size = QgsSymbolLayerV2Utils::sizeInPixelsFromSldUom( uom, size );
2170+
borderWidth = QgsSymbolLayerV2Utils::sizeInPixelsFromSldUom( uom, borderWidth );
2171+
21622172
double angle = 0.0;
21632173
QString angleFunc;
21642174
if ( QgsSymbolLayerV2Utils::rotationFromSldElement( graphicElem, angleFunc ) )
@@ -2170,6 +2180,7 @@ QgsSymbolLayerV2* QgsSVGFillSymbolLayer::createFromSld( QDomElement &element )
21702180
}
21712181

21722182
QgsSVGFillSymbolLayer* sl = new QgsSVGFillSymbolLayer( path, size, angle );
2183+
sl->setOutputUnit( QgsSymbolV2::Pixel );
21732184
sl->setSvgFillColor( fillColor );
21742185
sl->setSvgOutlineColor( borderColor );
21752186
sl->setSvgOutlineWidth( borderWidth );
@@ -3018,7 +3029,12 @@ QgsSymbolLayerV2* QgsLinePatternFillSymbolLayer::createFromSld( QDomElement &ele
30183029
offset = sqrt( pow( vectOffset.x(), 2 ) + pow( vectOffset.y(), 2 ) );
30193030
}
30203031

3032+
QString uom = element.attribute( QString( "uom" ), "" );
3033+
size = QgsSymbolLayerV2Utils::sizeInPixelsFromSldUom( uom, size );
3034+
lineWidth = QgsSymbolLayerV2Utils::sizeInPixelsFromSldUom( uom, lineWidth );
3035+
30213036
QgsLinePatternFillSymbolLayer* sl = new QgsLinePatternFillSymbolLayer();
3037+
sl->setOutputUnit( QgsSymbolV2::Pixel );
30223038
sl->setColor( lineColor );
30233039
sl->setLineWidth( lineWidth );
30243040
sl->setLineAngle( angle );

‎src/core/symbology-ng/qgslinesymbollayerv2.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,12 @@ QgsSymbolLayerV2* QgsSimpleLineSymbolLayerV2::createFromSld( QDomElement &elemen
471471
offset = d;
472472
}
473473

474+
QString uom = element.attribute( QString( "uom" ), "" );
475+
width = QgsSymbolLayerV2Utils::sizeInPixelsFromSldUom( uom, width );
476+
offset = QgsSymbolLayerV2Utils::sizeInPixelsFromSldUom( uom, offset );
477+
474478
QgsSimpleLineSymbolLayerV2* l = new QgsSimpleLineSymbolLayerV2( color, width, penStyle );
479+
l->setOutputUnit( QgsSymbolV2::Pixel );
475480
l->setOffset( offset );
476481
l->setPenJoinStyle( penJoinStyle );
477482
l->setPenCapStyle( penCapStyle );
@@ -1551,7 +1556,12 @@ QgsSymbolLayerV2* QgsMarkerLineSymbolLayerV2::createFromSld( QDomElement &elemen
15511556
offset = d;
15521557
}
15531558

1559+
QString uom = element.attribute( QString( "uom" ), "" );
1560+
interval = QgsSymbolLayerV2Utils::sizeInPixelsFromSldUom( uom, interval );
1561+
offset = QgsSymbolLayerV2Utils::sizeInPixelsFromSldUom( uom, offset );
1562+
15541563
QgsMarkerLineSymbolLayerV2* x = new QgsMarkerLineSymbolLayerV2( rotateMarker );
1564+
x->setOutputUnit( QgsSymbolV2::Pixel );
15551565
x->setPlacement( placement );
15561566
x->setInterval( interval );
15571567
x->setSubSymbol( marker );

‎src/core/symbology-ng/qgsmarkersymbollayerv2.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,7 +1239,13 @@ QgsSymbolLayerV2* QgsSimpleMarkerSymbolLayerV2::createFromSld( QDomElement &elem
12391239

12401240
Shape shape = decodeShape( name );
12411241

1242+
QString uom = element.attribute( QString( "uom" ), "" );
1243+
size = QgsSymbolLayerV2Utils::sizeInPixelsFromSldUom( uom, size );
1244+
offset.setX( QgsSymbolLayerV2Utils::sizeInPixelsFromSldUom( uom, offset.x() ) );
1245+
offset.setY( QgsSymbolLayerV2Utils::sizeInPixelsFromSldUom( uom, offset.y() ) );
1246+
12421247
QgsSimpleMarkerSymbolLayerV2 *m = new QgsSimpleMarkerSymbolLayerV2( shape, size );
1248+
m->setOutputUnit( QgsSymbolV2::Pixel );
12431249
m->setColor( color );
12441250
m->setBorderColor( borderColor );
12451251
m->setAngle( angle );
@@ -2266,6 +2272,9 @@ QgsSymbolLayerV2* QgsSvgMarkerSymbolLayerV2::createFromSld( QDomElement &element
22662272
if ( !QgsSymbolLayerV2Utils::externalGraphicFromSld( graphicElem, path, mimeType, fillColor, size ) )
22672273
return nullptr;
22682274

2275+
QString uom = element.attribute( QString( "uom" ), "" );
2276+
size = QgsSymbolLayerV2Utils::sizeInPixelsFromSldUom( uom, size );
2277+
22692278
if ( mimeType != "image/svg+xml" )
22702279
return nullptr;
22712280

@@ -2283,6 +2292,7 @@ QgsSymbolLayerV2* QgsSvgMarkerSymbolLayerV2::createFromSld( QDomElement &element
22832292
QgsSymbolLayerV2Utils::displacementFromSldElement( graphicElem, offset );
22842293

22852294
QgsSvgMarkerSymbolLayerV2* m = new QgsSvgMarkerSymbolLayerV2( path, size );
2295+
m->setOutputUnit( QgsSymbolV2::Pixel );
22862296
m->setFillColor( fillColor );
22872297
//m->setOutlineColor( outlineColor );
22882298
//m->setOutlineWidth( outlineWidth );
@@ -2945,7 +2955,13 @@ QgsSymbolLayerV2* QgsFontMarkerSymbolLayerV2::createFromSld( QDomElement &elemen
29452955
QPointF offset;
29462956
QgsSymbolLayerV2Utils::displacementFromSldElement( graphicElem, offset );
29472957

2958+
QString uom = element.attribute( QString( "uom" ), "" );
2959+
offset.setX( QgsSymbolLayerV2Utils::sizeInPixelsFromSldUom( uom, offset.x() ) );
2960+
offset.setY( QgsSymbolLayerV2Utils::sizeInPixelsFromSldUom( uom, offset.y() ) );
2961+
size = QgsSymbolLayerV2Utils::sizeInPixelsFromSldUom( uom, size );
2962+
29482963
QgsMarkerSymbolLayerV2 *m = new QgsFontMarkerSymbolLayerV2( fontFamily, chr, size, color );
2964+
m->setOutputUnit( QgsSymbolV2::Pixel );
29492965
m->setAngle( angle );
29502966
m->setOffset( offset );
29512967
return m;

‎src/core/symbology-ng/qgssymbollayerv2utils.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4231,3 +4231,23 @@ void QgsSymbolLayerV2Utils::mergeScaleDependencies( int mScaleMinDenom, int mSca
42314231
props[ "scaleMaxDenom" ] = QString::number( qMin( parentScaleMaxDenom, mScaleMaxDenom ) );
42324232
}
42334233
}
4234+
4235+
double QgsSymbolLayerV2Utils::sizeInPixelsFromSldUom( const QString &uom, double size )
4236+
{
4237+
double scale = 1.0;
4238+
4239+
if ( uom == QLatin1String( "http://www.opengeospatial.org/se/units/metre" ) )
4240+
{
4241+
scale = 1.0 / 0.00028; // from meters to pixels
4242+
}
4243+
else if ( uom == QLatin1String( "http://www.opengeospatial.org/se/units/foot" ) )
4244+
{
4245+
scale = 304.8 / 0.28; // from feet to pixels
4246+
}
4247+
else
4248+
{
4249+
scale = 1.0; // from pixels to pixels (default unit)
4250+
}
4251+
4252+
return size * scale;
4253+
}

‎src/core/symbology-ng/qgssymbollayerv2utils.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,14 @@ class CORE_EXPORT QgsSymbolLayerV2Utils
103103
static QString encodeScaleMethod( QgsSymbolV2::ScaleMethod scaleMethod );
104104
static QgsSymbolV2::ScaleMethod decodeScaleMethod( const QString& str );
105105

106+
/** Returns the size scaled in pixels according to the uom attribute.
107+
* @param uom The uom attribute from SLD 1.1 version
108+
* @param size The original size
109+
* @returns the size in pixels
110+
* @note added in QGIS 2.18 and 3.0
111+
*/
112+
static double sizeInPixelsFromSldUom( const QString &uom, double size );
113+
106114
static QPainter::CompositionMode decodeBlendMode( const QString& s );
107115

108116
static QIcon symbolPreviewIcon( QgsSymbolV2* symbol, QSize size );

‎tests/src/python/test_qgssymbollayerv2_readsld.py

Lines changed: 299 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,24 @@
2626
import qgis # NOQA
2727

2828
import os
29+
from qgis.PyQt.QtXml import QDomDocument
2930
from qgis.testing import start_app, unittest
3031
from qgis.core import (QgsVectorLayer,
3132
QgsFeature,
3233
QgsGeometry,
33-
QgsPoint
34+
QgsPoint,
35+
QgsUnitTypes,
36+
QgsPoint,
37+
QgsSvgMarkerSymbolLayerV2,
38+
QgsEllipseSymbolLayerV2,
39+
QgsSimpleFillSymbolLayerV2,
40+
QgsSVGFillSymbolLayer,
41+
QgsLinePatternFillSymbolLayer,
42+
QgsSimpleLineSymbolLayerV2,
43+
QgsMarkerLineSymbolLayerV2,
44+
QgsSimpleMarkerSymbolLayerV2,
45+
QgsFontMarkerSymbolLayerV2,
46+
QgsSymbolV2
3447
)
3548
from qgis.testing import unittest
3649
from qgis.testing.mocked import get_iface
@@ -52,6 +65,28 @@ def createLayerWithOneLine():
5265
return linelayer
5366

5467

68+
def createLayerWithOnePoint():
69+
layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer",
70+
"addfeat", "memory")
71+
pr = layer.dataProvider()
72+
f = QgsFeature()
73+
f.setAttributes(["test", 123])
74+
f.setGeometry(QgsGeometry.fromPoint(QgsPoint(100, 200)))
75+
assert pr.addFeatures([f])
76+
assert layer.pendingFeatureCount() == 1
77+
return layer
78+
79+
80+
def createLayerWithOnePolygon():
81+
layer = QgsVectorLayer("Polygon?crs=epsg:3111&field=pk:int", "vl", "memory")
82+
assert layer.isValid()
83+
f1 = QgsFeature(layer.dataProvider().fields(), 1)
84+
f1.setAttribute("pk", 1)
85+
f1.setGeometry(QgsGeometry.fromPolygon([[QgsPoint(2484588, 2425722), QgsPoint(2482767, 2398853), QgsPoint(2520109, 2397715), QgsPoint(2520792, 2425494), QgsPoint(2484588, 2425722)]]))
86+
assert layer.dataProvider().addFeatures([f1])
87+
return layer
88+
89+
5590
class TestQgsSymbolLayerReadSld(unittest.TestCase):
5691

5792
"""
@@ -70,17 +105,17 @@ def test_Literal_within_CSSParameter(self):
70105
props = layer.rendererV2().symbol().symbolLayers()[0].properties()
71106

72107
def testLineColor():
73-
# stroke CSSParameter within ogc:Literal
108+
# border CSSParameter within ogc:Literal
74109
# expected color is #003EBA, RGB 0,62,186
75110
self.assertEqual(layer.rendererV2().symbol().symbolLayers()[0].color().name(), '#003eba')
76111

77112
def testLineWidth():
78-
# stroke-width CSSParameter within ogc:Literal
113+
# border-width CSSParameter within ogc:Literal
79114
self.assertEqual(props['line_width'], '2')
80115

81116
def testLineOpacity():
82-
# stroke-opacity CSSParameter NOT within ogc:Literal
83-
# stroke-opacity=0.1
117+
# border-opacity CSSParameter NOT within ogc:Literal
118+
# border-opacity=0.1
84119
self.assertEqual(props['line_color'], '0,62,186,25')
85120

86121
testLineColor()
@@ -112,6 +147,265 @@ def testSimpleMarkerRotation(self):
112147
props = layer.rendererV2().symbol().symbolLayers()[0].properties()
113148
self.assertEqual(props['angle'], '50')
114149

150+
def testSymbolSizeUom(self):
151+
# create a layer
152+
layer = createLayerWithOnePoint()
153+
154+
# load a sld with marker size without uom attribute (pixels)
155+
sld = 'symbol_layer/QgsSvgMarkerSymbolLayerV2.sld'
156+
mFilePath = os.path.join(TEST_DATA_DIR, sld)
157+
layer.loadSldStyle(mFilePath)
158+
159+
sld_size_px = 12
160+
161+
sl = layer.rendererV2().symbol().symbolLayers()[0]
162+
size = sl.size()
163+
unit = sl.outputUnit()
164+
self.assertEqual(unit, QgsSymbolV2.Pixel)
165+
self.assertEqual(size, sld_size_px)
166+
167+
# load a sld with marker size with uom attribute in pixel
168+
sld = 'symbol_layer/QgsSvgMarkerSymbolLayerUomPixel.sld'
169+
mFilePath = os.path.join(TEST_DATA_DIR, sld)
170+
layer.loadSldStyle(mFilePath)
171+
172+
sld_size_px = 12
173+
174+
sl = layer.rendererV2().symbol().symbolLayers()[0]
175+
size = sl.size()
176+
unit = sl.outputUnit()
177+
self.assertEqual(unit, QgsSymbolV2.Pixel)
178+
self.assertEqual(size, sld_size_px)
179+
180+
# load a sld with marker size with uom attribute in meter
181+
sld = 'symbol_layer/QgsSvgMarkerSymbolLayerUomMetre.sld'
182+
mFilePath = os.path.join(TEST_DATA_DIR, sld)
183+
layer.loadSldStyle(mFilePath)
184+
185+
sld_size_px = 12 / (0.28 * 0.001)
186+
187+
sl = layer.rendererV2().symbol().symbolLayers()[0]
188+
size = sl.size()
189+
unit = sl.outputUnit()
190+
self.assertEqual(unit, QgsSymbolV2.Pixel)
191+
self.assertAlmostEqual(size, sld_size_px, delta=0.1)
192+
193+
# load a sld with marker size with uom attribute in foot
194+
sld = 'symbol_layer/QgsSvgMarkerSymbolLayerUomFoot.sld'
195+
mFilePath = os.path.join(TEST_DATA_DIR, sld)
196+
layer.loadSldStyle(mFilePath)
197+
198+
sld_size_px = 12 * (304.8 / 0.28)
199+
200+
sl = layer.rendererV2().symbol().symbolLayers()[0]
201+
size = sl.size()
202+
unit = sl.outputUnit()
203+
self.assertEqual(unit, QgsSymbolV2.Pixel)
204+
self.assertAlmostEqual(size, sld_size_px, delta=0.1)
205+
206+
def testSymbolSize(self):
207+
# create a layers
208+
layer = createLayerWithOnePoint()
209+
player = createLayerWithOnePolygon()
210+
211+
# size test for QgsEllipseSymbolLayer
212+
sld = 'symbol_layer/QgsEllipseSymbolLayerV2.sld'
213+
mFilePath = os.path.join(TEST_DATA_DIR, sld)
214+
layer.loadSldStyle(mFilePath)
215+
216+
sld_size_px = 7
217+
sld_border_width_px = 1
218+
219+
sl = layer.rendererV2().symbol().symbolLayers()[0]
220+
size = sl.symbolWidth()
221+
border_width = sl.outlineWidth()
222+
unit = sl.outputUnit()
223+
self.assertTrue(isinstance(sl, QgsEllipseSymbolLayerV2))
224+
self.assertEqual(unit, QgsSymbolV2.Pixel)
225+
self.assertEqual(size, sld_size_px)
226+
self.assertEqual(border_width, sld_border_width_px)
227+
228+
# size test for QgsVectorFieldSymbolLayer
229+
# createFromSld not implemented
230+
231+
# size test for QgsSimpleFillSymbolLayer
232+
sld = 'symbol_layer/QgsSimpleFillSymbolLayerV2.sld'
233+
mFilePath = os.path.join(TEST_DATA_DIR, sld)
234+
player.loadSldStyle(mFilePath)
235+
236+
sld_border_width_px = 0.26
237+
238+
sl = player.rendererV2().symbol().symbolLayers()[0]
239+
border_width = sl.borderWidth()
240+
unit = sl.outputUnit()
241+
self.assertTrue(isinstance(sl, QgsSimpleFillSymbolLayerV2))
242+
self.assertEqual(unit, QgsSymbolV2.Pixel)
243+
self.assertEqual(border_width, sld_border_width_px)
244+
245+
# size test for QgsSVGFillSymbolLayer
246+
sld = 'symbol_layer/QgsSVGFillSymbolLayer.sld'
247+
mFilePath = os.path.join(TEST_DATA_DIR, sld)
248+
player.loadSldStyle(mFilePath)
249+
250+
sld_size_px = 6
251+
sld_border_width_px = 3
252+
253+
sl = player.rendererV2().symbol().symbolLayers()[0]
254+
size = sl.patternWidth()
255+
border_width = sl.svgOutlineWidth()
256+
unit = sl.outputUnit()
257+
self.assertTrue(isinstance(sl, QgsSVGFillSymbolLayer))
258+
self.assertEqual(unit, QgsSymbolV2.Pixel)
259+
self.assertEqual(size, sld_size_px)
260+
self.assertEqual(border_width, sld_border_width_px)
261+
262+
# size test for QgsSvgMarkerSymbolLayer
263+
sld = 'symbol_layer/QgsSvgMarkerSymbolLayerV2.sld'
264+
mFilePath = os.path.join(TEST_DATA_DIR, sld)
265+
layer.loadSldStyle(mFilePath)
266+
267+
sld_size_px = 12
268+
269+
sl = layer.rendererV2().symbol().symbolLayers()[0]
270+
size = sl.size()
271+
unit = sl.outputUnit()
272+
self.assertTrue(isinstance(sl, QgsSvgMarkerSymbolLayerV2))
273+
self.assertEqual(unit, QgsSymbolV2.Pixel)
274+
self.assertEqual(size, sld_size_px)
275+
276+
# size test for QgsPointPatternFillSymbolLayer
277+
# createFromSld not implemented
278+
279+
# size test for QgsLinePatternFillSymbolLayer
280+
sld = 'symbol_layer/QgsLinePatternFillSymbolLayer.sld'
281+
mFilePath = os.path.join(TEST_DATA_DIR, sld)
282+
player.loadSldStyle(mFilePath)
283+
284+
sld_size_px = 4
285+
sld_border_width_px = 1.5
286+
287+
sl = player.rendererV2().symbol().symbolLayers()[0]
288+
size = sl.distance()
289+
border_width = sl.lineWidth()
290+
unit = sl.outputUnit()
291+
self.assertTrue(isinstance(sl, QgsLinePatternFillSymbolLayer))
292+
self.assertEqual(unit, QgsSymbolV2.Pixel)
293+
self.assertEqual(size, sld_size_px)
294+
self.assertEqual(border_width, sld_border_width_px)
295+
296+
# test size for QgsSimpleLineSymbolLayer
297+
sld = 'symbol_layer/QgsSimpleLineSymbolLayerV2.sld'
298+
mFilePath = os.path.join(TEST_DATA_DIR, sld)
299+
player.loadSldStyle(mFilePath)
300+
301+
sld_border_width_px = 1.26
302+
303+
sl = player.rendererV2().symbol().symbolLayers()[0]
304+
border_width = sl.width()
305+
unit = sl.outputUnit()
306+
self.assertTrue(isinstance(sl, QgsSimpleLineSymbolLayerV2))
307+
self.assertEqual(unit, QgsSymbolV2.Pixel)
308+
self.assertEqual(border_width, sld_border_width_px)
309+
310+
# test size for QgsMarkerLineSymbolLayer
311+
sld = 'symbol_layer/QgsMarkerLineSymbolLayerV2.sld'
312+
mFilePath = os.path.join(TEST_DATA_DIR, sld)
313+
player.loadSldStyle(mFilePath)
314+
315+
sld_interval_px = 3.3
316+
sld_offset_px = 6.6
317+
318+
sl = player.rendererV2().symbol().symbolLayers()[0]
319+
interval = sl.interval()
320+
offset = sl.offset()
321+
unit = sl.outputUnit()
322+
self.assertTrue(isinstance(sl, QgsMarkerLineSymbolLayerV2))
323+
self.assertEqual(unit, QgsSymbolV2.Pixel)
324+
self.assertEqual(interval, sld_interval_px)
325+
self.assertEqual(offset, sld_offset_px)
326+
327+
# test size for QgsSimpleMarkerSymbolLayer
328+
sld = 'symbol_layer/QgsSimpleMarkerSymbolLayerV2.sld'
329+
mFilePath = os.path.join(TEST_DATA_DIR, sld)
330+
layer.loadSldStyle(mFilePath)
331+
332+
sld_size_px = 6
333+
334+
sld_displacement_x_px = 3.3
335+
sld_displacement_y_px = 6.6
336+
337+
sl = layer.rendererV2().symbol().symbolLayers()[0]
338+
size = sl.size()
339+
offset = sl.offset()
340+
unit = sl.outputUnit()
341+
self.assertTrue(isinstance(sl, QgsSimpleMarkerSymbolLayerV2))
342+
self.assertEqual(unit, QgsSymbolV2.Pixel)
343+
self.assertEqual(size, sld_size_px)
344+
self.assertEqual(offset.x(), sld_displacement_x_px)
345+
self.assertEqual(offset.y(), sld_displacement_y_px)
346+
347+
# test size for QgsSVGMarkerSymbolLayer
348+
sld = 'symbol_layer/QgsSvgMarkerSymbolLayerV2.sld'
349+
mFilePath = os.path.join(TEST_DATA_DIR, sld)
350+
layer.loadSldStyle(mFilePath)
351+
352+
sld_size_px = 12
353+
354+
sl = layer.rendererV2().symbol().symbolLayers()[0]
355+
size = sl.size()
356+
self.assertTrue(isinstance(sl, QgsSvgMarkerSymbolLayerV2))
357+
self.assertEqual(unit, QgsSymbolV2.Pixel)
358+
self.assertEqual(size, sld_size_px)
359+
360+
# test size for QgsFontMarkerSymbolLayer
361+
sld = 'symbol_layer/QgsFontMarkerSymbolLayerV2.sld'
362+
mFilePath = os.path.join(TEST_DATA_DIR, sld)
363+
layer.loadSldStyle(mFilePath)
364+
365+
sld_size_px = 6.23
366+
367+
sl = layer.rendererV2().symbol().symbolLayers()[0]
368+
size = sl.size()
369+
self.assertTrue(isinstance(sl, QgsFontMarkerSymbolLayerV2))
370+
self.assertEqual(unit, QgsSymbolV2.Pixel)
371+
self.assertEqual(size, sld_size_px)
372+
373+
def testSymbolSizeAfterReload(self):
374+
# create a layer
375+
layer = createLayerWithOnePoint()
376+
377+
# load a sld with marker size
378+
sld = 'symbol_layer/QgsSvgMarkerSymbolLayerV2.sld'
379+
mFilePath = os.path.join(TEST_DATA_DIR, sld)
380+
layer.loadSldStyle(mFilePath)
381+
382+
# get the size and unit of the symbol
383+
sl = layer.rendererV2().symbol().symbolLayers()[0]
384+
first_size = sl.size()
385+
first_unit = sl.outputUnit() # in pixels
386+
387+
# export sld into a qdomdocument with namespace processing activated
388+
doc = QDomDocument()
389+
msg = ""
390+
layer.exportSldStyle(doc, msg)
391+
doc.setContent(doc.toString(), True)
392+
self.assertTrue(msg == "")
393+
394+
# reload the same sld
395+
root = doc.firstChildElement("StyledLayerDescriptor")
396+
el = root.firstChildElement("NamedLayer")
397+
layer.readSld(el, msg)
398+
399+
# extract the size and unit of symbol
400+
sl = layer.rendererV2().symbol().symbolLayers()[0]
401+
second_size = sl.size()
402+
second_unit = sl.outputUnit()
403+
404+
# size and unit should be the same after export and reload the same
405+
# sld description
406+
self.assertEqual(first_size, second_size)
407+
self.assertEqual(first_unit, second_unit)
408+
115409

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

‎tests/testdata/symbol_layer/QgsMarkerLineSymbolLayerV2.sld

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
<VendorOption name="placement">centralPoint</VendorOption>
1212
<se:Stroke>
1313
<se:GraphicStroke>
14+
<se:Gap>3.3</se:Gap>
15+
<se:PerpendicularOffset>6.6</se:PerpendicularOffset>
1416
<se:Graphic>
1517
<se:Mark>
1618
<se:WellKnownName>circle</se:WellKnownName>

‎tests/testdata/symbol_layer/QgsSimpleMarkerSymbolLayerV2.sld

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
<se:Name>Single symbol</se:Name>
1010
<se:PointSymbolizer>
1111
<se:Graphic>
12+
<se:Displacement>
13+
<se:DisplacementX>3.3</se:DisplacementX>
14+
<se:DisplacementY>6.6</se:DisplacementY>
15+
</se:Displacement>
1216
<se:Mark>
1317
<se:WellKnownName>pentagon</se:WellKnownName>
1418
<se:Fill>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<StyledLayerDescriptor xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd" xmlns:se="http://www.opengis.net/se">
3+
<NamedLayer>
4+
<se:Name>022cs000</se:Name>
5+
<UserStyle>
6+
<se:Name>022cs000</se:Name>
7+
<se:FeatureTypeStyle>
8+
<se:Rule>
9+
<se:Name>Single symbol</se:Name>
10+
<se:PointSymbolizer uom="http://www.opengeospatial.org/se/units/foot">
11+
<se:Graphic>
12+
<se:ExternalGraphic>
13+
<OnlineResource xlink:type="simple" xlink:href="file:///gpsicons/skull.svg"/>
14+
<Format>image/svg+xml</Format>
15+
</se:ExternalGraphic>
16+
<se:Size>12</se:Size>
17+
<se:Rotation>
18+
<ogc:Literal>45</ogc:Literal>
19+
</se:Rotation>
20+
</se:Graphic>
21+
</se:PointSymbolizer>
22+
</se:Rule>
23+
</se:FeatureTypeStyle>
24+
</UserStyle>
25+
</NamedLayer>
26+
</StyledLayerDescriptor>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<StyledLayerDescriptor xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd" xmlns:se="http://www.opengis.net/se">
3+
<NamedLayer>
4+
<se:Name>022cs000</se:Name>
5+
<UserStyle>
6+
<se:Name>022cs000</se:Name>
7+
<se:FeatureTypeStyle>
8+
<se:Rule>
9+
<se:Name>Single symbol</se:Name>
10+
<se:PointSymbolizer uom="http://www.opengeospatial.org/se/units/metre">
11+
<se:Graphic>
12+
<se:ExternalGraphic>
13+
<OnlineResource xlink:type="simple" xlink:href="file:///gpsicons/skull.svg"/>
14+
<Format>image/svg+xml</Format>
15+
</se:ExternalGraphic>
16+
<se:Size>12</se:Size>
17+
<se:Rotation>
18+
<ogc:Literal>45</ogc:Literal>
19+
</se:Rotation>
20+
</se:Graphic>
21+
</se:PointSymbolizer>
22+
</se:Rule>
23+
</se:FeatureTypeStyle>
24+
</UserStyle>
25+
</NamedLayer>
26+
</StyledLayerDescriptor>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<StyledLayerDescriptor xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd" xmlns:se="http://www.opengis.net/se">
3+
<NamedLayer>
4+
<se:Name>022cs000</se:Name>
5+
<UserStyle>
6+
<se:Name>022cs000</se:Name>
7+
<se:FeatureTypeStyle>
8+
<se:Rule>
9+
<se:Name>Single symbol</se:Name>
10+
<se:PointSymbolizer uom="http://www.opengeospatial.org/se/units/pixel">
11+
<se:Graphic>
12+
<se:ExternalGraphic>
13+
<OnlineResource xlink:type="simple" xlink:href="file:///gpsicons/skull.svg"/>
14+
<Format>image/svg+xml</Format>
15+
</se:ExternalGraphic>
16+
<se:Size>12</se:Size>
17+
<se:Rotation>
18+
<ogc:Literal>45</ogc:Literal>
19+
</se:Rotation>
20+
</se:Graphic>
21+
</se:PointSymbolizer>
22+
</se:Rule>
23+
</se:FeatureTypeStyle>
24+
</UserStyle>
25+
</NamedLayer>
26+
</StyledLayerDescriptor>

0 commit comments

Comments
 (0)
Please sign in to comment.