Skip to content

Commit 0a82ab5

Browse files
author
Hugo Mercier
authoredMay 19, 2017
Merge pull request #4432 from pblottiere/bugfix_sld
[bugfix] Fix unit of sizes when reading a SLD file (uom attribute from SLD 1.1 version is supported)
2 parents fe2350c + 0c72d4b commit 0a82ab5

13 files changed

+460
-1
lines changed
 

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,14 @@ class QgsSymbolLayerUtils
9090
*/
9191
static QgsUnitTypes::RenderUnit decodeSldUom( const QString &str, double *scaleFactor );
9292

93+
/** Returns the size scaled in pixels according to the uom attribute.
94+
* \param uom The uom attribute from SLD 1.1 version
95+
* \param size The original size
96+
* \returns the size in pixels
97+
* \since QGIS 3.0
98+
*/
99+
static double sizeInPixelsFromSldUom( const QString &uom, double size );
100+
93101
static QString encodeScaleMethod( QgsSymbol::ScaleMethod scaleMethod );
94102
static QgsSymbol::ScaleMethod decodeScaleMethod( const QString &str );
95103

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,10 @@ QgsSymbolLayer *QgsEllipseSymbolLayer::createFromSld( QDomElement &element )
451451
if ( !QgsSymbolLayerUtils::wellKnownMarkerFromSld( graphicElem, name, fillColor, strokeColor, strokeStyle, strokeWidth, size ) )
452452
return nullptr;
453453

454+
QString uom = element.attribute( QStringLiteral( "uom" ), "" );
455+
size = QgsSymbolLayerUtils::sizeInPixelsFromSldUom( uom, size );
456+
strokeWidth = QgsSymbolLayerUtils::sizeInPixelsFromSldUom( uom, strokeWidth );
457+
454458
double angle = 0.0;
455459
QString angleFunc;
456460
if ( QgsSymbolLayerUtils::rotationFromSldElement( graphicElem, angleFunc ) )
@@ -462,6 +466,7 @@ QgsSymbolLayer *QgsEllipseSymbolLayer::createFromSld( QDomElement &element )
462466
}
463467

464468
QgsEllipseSymbolLayer *m = new QgsEllipseSymbolLayer();
469+
m->setOutputUnit( QgsUnitTypes::RenderUnit::RenderPixels );
465470
m->setSymbolName( name );
466471
m->setFillColor( fillColor );
467472
m->setStrokeColor( strokeColor );

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,13 @@ QgsSymbolLayer *QgsSimpleFillSymbolLayer::createFromSld( QDomElement &element )
381381
QPointF offset;
382382
QgsSymbolLayerUtils::displacementFromSldElement( element, offset );
383383

384+
QString uom = element.attribute( QStringLiteral( "uom" ), "" );
385+
offset.setX( QgsSymbolLayerUtils::sizeInPixelsFromSldUom( uom, offset.x() ) );
386+
offset.setY( QgsSymbolLayerUtils::sizeInPixelsFromSldUom( uom, offset.y() ) );
387+
strokeWidth = QgsSymbolLayerUtils::sizeInPixelsFromSldUom( uom, strokeWidth );
388+
384389
QgsSimpleFillSymbolLayer *sl = new QgsSimpleFillSymbolLayer( color, fillStyle, strokeColor, strokeStyle, strokeWidth );
390+
sl->setOutputUnit( QgsUnitTypes::RenderUnit::RenderPixels );
385391
sl->setOffset( offset );
386392
return sl;
387393
}
@@ -2134,6 +2140,10 @@ QgsSymbolLayer *QgsSVGFillSymbolLayer::createFromSld( QDomElement &element )
21342140

21352141
QgsSymbolLayerUtils::lineFromSld( graphicElem, penStyle, strokeColor, strokeWidth );
21362142

2143+
QString uom = element.attribute( QStringLiteral( "uom" ), "" );
2144+
size = QgsSymbolLayerUtils::sizeInPixelsFromSldUom( uom, size );
2145+
strokeWidth = QgsSymbolLayerUtils::sizeInPixelsFromSldUom( uom, strokeWidth );
2146+
21372147
double angle = 0.0;
21382148
QString angleFunc;
21392149
if ( QgsSymbolLayerUtils::rotationFromSldElement( graphicElem, angleFunc ) )
@@ -2145,6 +2155,7 @@ QgsSymbolLayer *QgsSVGFillSymbolLayer::createFromSld( QDomElement &element )
21452155
}
21462156

21472157
QgsSVGFillSymbolLayer *sl = new QgsSVGFillSymbolLayer( path, size, angle );
2158+
sl->setOutputUnit( QgsUnitTypes::RenderUnit::RenderPixels );
21482159
sl->setSvgFillColor( fillColor );
21492160
sl->setSvgStrokeColor( strokeColor );
21502161
sl->setSvgStrokeWidth( strokeWidth );
@@ -2950,7 +2961,12 @@ QgsSymbolLayer *QgsLinePatternFillSymbolLayer::createFromSld( QDomElement &eleme
29502961
offset = sqrt( pow( vectOffset.x(), 2 ) + pow( vectOffset.y(), 2 ) );
29512962
}
29522963

2964+
QString uom = element.attribute( QStringLiteral( "uom" ), "" );
2965+
size = QgsSymbolLayerUtils::sizeInPixelsFromSldUom( uom, size );
2966+
lineWidth = QgsSymbolLayerUtils::sizeInPixelsFromSldUom( uom, lineWidth );
2967+
29532968
QgsLinePatternFillSymbolLayer *sl = new QgsLinePatternFillSymbolLayer();
2969+
sl->setOutputUnit( QgsUnitTypes::RenderUnit::RenderPixels );
29542970
sl->setColor( lineColor );
29552971
sl->setLineWidth( lineWidth );
29562972
sl->setLineAngle( angle );

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,12 @@ QgsSymbolLayer *QgsSimpleLineSymbolLayer::createFromSld( QDomElement &element )
462462
offset = d;
463463
}
464464

465+
QString uom = element.attribute( QStringLiteral( "uom" ), "" );
466+
width = QgsSymbolLayerUtils::sizeInPixelsFromSldUom( uom, width );
467+
offset = QgsSymbolLayerUtils::sizeInPixelsFromSldUom( uom, offset );
468+
465469
QgsSimpleLineSymbolLayer *l = new QgsSimpleLineSymbolLayer( color, width, penStyle );
470+
l->setOutputUnit( QgsUnitTypes::RenderUnit::RenderPixels );
466471
l->setOffset( offset );
467472
l->setPenJoinStyle( penJoinStyle );
468473
l->setPenCapStyle( penCapStyle );
@@ -1518,7 +1523,12 @@ QgsSymbolLayer *QgsMarkerLineSymbolLayer::createFromSld( QDomElement &element )
15181523
offset = d;
15191524
}
15201525

1526+
QString uom = element.attribute( QStringLiteral( "uom" ), "" );
1527+
interval = QgsSymbolLayerUtils::sizeInPixelsFromSldUom( uom, interval );
1528+
offset = QgsSymbolLayerUtils::sizeInPixelsFromSldUom( uom, offset );
1529+
15211530
QgsMarkerLineSymbolLayer *x = new QgsMarkerLineSymbolLayer( rotateMarker );
1531+
x->setOutputUnit( QgsUnitTypes::RenderUnit::RenderPixels );
15221532
x->setPlacement( placement );
15231533
x->setInterval( interval );
15241534
x->setSubSymbol( marker.release() );

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,7 +1194,13 @@ QgsSymbolLayer *QgsSimpleMarkerSymbolLayer::createFromSld( QDomElement &element
11941194

11951195
Shape shape = decodeShape( name );
11961196

1197+
QString uom = element.attribute( QStringLiteral( "uom" ), "" );
1198+
size = QgsSymbolLayerUtils::sizeInPixelsFromSldUom( uom, size );
1199+
offset.setX( QgsSymbolLayerUtils::sizeInPixelsFromSldUom( uom, offset.x() ) );
1200+
offset.setY( QgsSymbolLayerUtils::sizeInPixelsFromSldUom( uom, offset.y() ) );
1201+
11971202
QgsSimpleMarkerSymbolLayer *m = new QgsSimpleMarkerSymbolLayer( shape, size );
1203+
m->setOutputUnit( QgsUnitTypes::RenderUnit::RenderPixels );
11981204
m->setColor( color );
11991205
m->setStrokeColor( strokeColor );
12001206
m->setAngle( angle );
@@ -2217,6 +2223,9 @@ QgsSymbolLayer *QgsSvgMarkerSymbolLayer::createFromSld( QDomElement &element )
22172223
if ( !QgsSymbolLayerUtils::externalGraphicFromSld( graphicElem, path, mimeType, fillColor, size ) )
22182224
return nullptr;
22192225

2226+
QString uom = element.attribute( QStringLiteral( "uom" ), "" );
2227+
size = QgsSymbolLayerUtils::sizeInPixelsFromSldUom( uom, size );
2228+
22202229
if ( mimeType != QLatin1String( "image/svg+xml" ) )
22212230
return nullptr;
22222231

@@ -2234,6 +2243,7 @@ QgsSymbolLayer *QgsSvgMarkerSymbolLayer::createFromSld( QDomElement &element )
22342243
QgsSymbolLayerUtils::displacementFromSldElement( graphicElem, offset );
22352244

22362245
QgsSvgMarkerSymbolLayer *m = new QgsSvgMarkerSymbolLayer( path, size );
2246+
m->setOutputUnit( QgsUnitTypes::RenderUnit::RenderPixels );
22372247
m->setFillColor( fillColor );
22382248
//m->setStrokeColor( strokeColor );
22392249
//m->setStrokeWidth( strokeWidth );
@@ -2874,7 +2884,13 @@ QgsSymbolLayer *QgsFontMarkerSymbolLayer::createFromSld( QDomElement &element )
28742884
QPointF offset;
28752885
QgsSymbolLayerUtils::displacementFromSldElement( graphicElem, offset );
28762886

2887+
QString uom = element.attribute( QStringLiteral( "uom" ), "" );
2888+
offset.setX( QgsSymbolLayerUtils::sizeInPixelsFromSldUom( uom, offset.x() ) );
2889+
offset.setY( QgsSymbolLayerUtils::sizeInPixelsFromSldUom( uom, offset.y() ) );
2890+
size = QgsSymbolLayerUtils::sizeInPixelsFromSldUom( uom, size );
2891+
28772892
QgsMarkerSymbolLayer *m = new QgsFontMarkerSymbolLayer( fontFamily, chr, size, color );
2893+
m->setOutputUnit( QgsUnitTypes::RenderUnit::RenderPixels );
28782894
m->setAngle( angle );
28792895
m->setOffset( offset );
28802896
return m;

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4037,3 +4037,23 @@ void QgsSymbolLayerUtils::mergeScaleDependencies( int mScaleMinDenom, int mScale
40374037
props[ QStringLiteral( "scaleMaxDenom" )] = QString::number( qMin( parentScaleMaxDenom, mScaleMaxDenom ) );
40384038
}
40394039
}
4040+
4041+
double QgsSymbolLayerUtils::sizeInPixelsFromSldUom( const QString &uom, double size )
4042+
{
4043+
double scale = 1.0;
4044+
4045+
if ( uom == QLatin1String( "http://www.opengeospatial.org/se/units/metre" ) )
4046+
{
4047+
scale = 1.0 / 0.00028; // from meters to pixels
4048+
}
4049+
else if ( uom == QLatin1String( "http://www.opengeospatial.org/se/units/foot" ) )
4050+
{
4051+
scale = 304.8 / 0.28; // from feet to pixels
4052+
}
4053+
else
4054+
{
4055+
scale = 1.0; // from pixels to pixels (default unit)
4056+
}
4057+
4058+
return size * scale;
4059+
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,14 @@ class CORE_EXPORT QgsSymbolLayerUtils
137137
*/
138138
static QgsUnitTypes::RenderUnit decodeSldUom( const QString &str, double *scaleFactor );
139139

140+
/** Returns the size scaled in pixels according to the uom attribute.
141+
* \param uom The uom attribute from SLD 1.1 version
142+
* \param size The original size
143+
* \returns the size in pixels
144+
* \since QGIS 3.0
145+
*/
146+
static double sizeInPixelsFromSldUom( const QString &uom, double size );
147+
140148
static QString encodeScaleMethod( QgsSymbol::ScaleMethod scaleMethod );
141149
static QgsSymbol::ScaleMethod decodeScaleMethod( const QString &str );
142150

‎tests/src/python/test_qgssymbollayer_readsld.py‎

Lines changed: 293 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,23 @@
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+
QgsUnitTypes,
35+
QgsPoint,
36+
QgsSvgMarkerSymbolLayer,
37+
QgsEllipseSymbolLayer,
38+
QgsSimpleFillSymbolLayer,
39+
QgsSVGFillSymbolLayer,
40+
QgsSvgMarkerSymbolLayer,
41+
QgsLinePatternFillSymbolLayer,
42+
QgsSimpleLineSymbolLayer,
43+
QgsMarkerLineSymbolLayer,
44+
QgsSimpleMarkerSymbolLayer,
45+
QgsFontMarkerSymbolLayer
3446
)
3547
from qgis.testing.mocked import get_iface
3648
from utilities import unitTestDataPath
@@ -51,6 +63,28 @@ def createLayerWithOneLine():
5163
return linelayer
5264

5365

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

5690
"""
@@ -111,6 +145,264 @@ def testSimpleMarkerRotation(self):
111145
props = layer.renderer().symbol().symbolLayers()[0].properties()
112146
self.assertEqual(props['angle'], '50')
113147

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

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

‎tests/testdata/symbol_layer/QgsMarkerLineSymbolLayer.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/QgsSimpleMarkerSymbolLayer.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.