28
28
import os
29
29
30
30
from qgis .PyQt .QtCore import pyqtWrapperType , Qt , QDir , QFile , QIODevice , QPointF
31
- from qgis .PyQt .QtXml import (QDomDocument , QDomElement )
31
+ from qgis .PyQt .QtXml import (
32
+ QDomDocument , QDomElement , QDomNode , QDomNamedNodeMap )
32
33
from qgis .PyQt .QtGui import QColor
33
34
34
- from qgis .core import QgsSimpleMarkerSymbolLayer
35
+ from qgis .core import (
36
+ QgsSimpleMarkerSymbolLayer , QgsUnitTypes , QgsSvgMarkerSymbolLayer ,
37
+ QgsFontMarkerSymbolLayer , QgsEllipseSymbolLayer , QgsSimpleLineSymbolLayer ,
38
+ QgsMarkerLineSymbolLayer , QgsMarkerSymbol , QgsSimpleFillSymbolLayer , QgsSVGFillSymbolLayer ,
39
+ QgsLinePatternFillSymbolLayer , QgsPointPatternFillSymbolLayer )
35
40
from qgis .testing import start_app , unittest
36
41
from utilities import unitTestDataPath
37
42
@@ -46,22 +51,355 @@ class TestQgsSymbolLayerCreateSld(unittest.TestCase):
46
51
This class tests the creation of SLD from QGis layers
47
52
"""
48
53
49
- def testSimpleMarkerSymbolLayer (self ):
54
+ def testSimpleMarkerRotation (self ):
50
55
symbol = QgsSimpleMarkerSymbolLayer (
51
56
'star' , QColor (255 , 0 , 0 ), QColor (0 , 255 , 0 ), 10 )
52
57
symbol .setAngle (50 )
53
- dom = QDomDocument ()
54
- root = dom .createElement ("FakeRoot" )
55
- dom .appendChild (root )
56
- symbol .toSld (dom , root , {})
57
- # print "This is the dom: " + dom.toString()
58
+ dom , root = self .symbolToSld (symbol )
59
+ # print( "Simple marker rotation: " + root.ownerDocument().toString())
58
60
61
+ self .assertStaticRotation (root , '50' )
62
+
63
+ def assertStaticRotation (self , root , expectedValue ):
59
64
# Check the rotation element is a literal, not a
60
65
rotation = root .elementsByTagName ('se:Rotation' ).item (0 )
61
66
literal = rotation .firstChild ()
62
67
self .assertEquals ("ogc:Literal" , literal .nodeName ())
63
- self .assertEquals ('50' , literal .firstChild ().nodeValue ())
68
+ self .assertEquals (expectedValue , literal .firstChild ().nodeValue ())
69
+
70
+ def assertStaticDisplacement (self , root , expectedDispX , expectedDispY ):
71
+ displacement = root .elementsByTagName ('se:Displacement' ).item (0 )
72
+ self .assertIsNotNone (displacement )
73
+ dx = displacement .firstChild ()
74
+ self .assertIsNotNone (dx )
75
+ self .assertEquals ("se:DisplacementX" , dx .nodeName ())
76
+ self .assertSldNumber (expectedDispX , dx .firstChild ().nodeValue ())
77
+ dy = displacement .lastChild ()
78
+ self .assertIsNotNone (dy )
79
+ self .assertEquals ("se:DisplacementY" , dy .nodeName ())
80
+ self .assertSldNumber (expectedDispY , dy .firstChild ().nodeValue ())
81
+
82
+ def assertSldNumber (self , expected , stringValue ):
83
+ value = float (stringValue )
84
+ self .assertFloatEquals (expected , value , 0.01 )
85
+
86
+ def assertFloatEquals (self , expected , actual , tol ):
87
+ self .assertLess (abs (expected - actual ), tol )
88
+
89
+ def testSimpleMarkerUnitDefault (self ):
90
+ symbol = QgsSimpleMarkerSymbolLayer (
91
+ 'star' , QColor (255 , 0 , 0 ), QColor (0 , 255 , 0 ), 10 )
92
+ symbol .setOutlineWidth (3 )
93
+ symbol .setOffset (QPointF (5 , 10 ))
94
+ dom , root = self .symbolToSld (symbol )
95
+ # print("Simple marker unit mm: " + root.ownerDocument().toString())
96
+
97
+ # Check the size has been rescaled to pixels
98
+ self .assertStaticSize (root , '36' )
99
+
100
+ # Check the same happened to the outline width
101
+ self .assertStrokeWidth (root , 2 , 11 )
102
+ self .assertStaticDisplacement (root , 18 , 36 )
103
+
104
+ def assertStrokeWidth (self , root , svgParameterIdx , expectedWidth ):
105
+ strokeWidth = root .elementsByTagName (
106
+ 'se:SvgParameter' ).item (svgParameterIdx )
107
+ svgParameterName = strokeWidth .attributes ().namedItem ('name' )
108
+ self .assertEquals ("stroke-width" , svgParameterName .nodeValue ())
109
+ self .assertSldNumber (
110
+ expectedWidth , strokeWidth .firstChild ().nodeValue ())
111
+
112
+ def testSimpleMarkerUnitPixels (self ):
113
+ symbol = QgsSimpleMarkerSymbolLayer (
114
+ 'star' , QColor (255 , 0 , 0 ), QColor (0 , 255 , 0 ), 10 )
115
+ symbol .setOutlineWidth (3 )
116
+ symbol .setOffset (QPointF (5 , 10 ))
117
+ symbol .setOutputUnit (QgsUnitTypes .RenderPixels )
118
+ dom , root = self .symbolToSld (symbol )
119
+ # print("Marker unit mm: " + root.ownerDocument().toString())
120
+
121
+ # Check the size has not been rescaled
122
+ self .assertStaticSize (root , '10' )
123
+
124
+ # Check the same happened to the outline width
125
+ self .assertStrokeWidth (root , 2 , 3 )
126
+ self .assertStaticDisplacement (root , 5 , 10 )
127
+
128
+ def testSvgMarkerUnitDefault (self ):
129
+ symbol = QgsSvgMarkerSymbolLayer ('symbols/star.svg' , 10 , 90 )
130
+ symbol .setOffset (QPointF (5 , 10 ))
131
+
132
+ dom , root = self .symbolToSld (symbol )
133
+ # print("Svg marker mm: " + dom.toString())
134
+
135
+ # Check the size has been rescaled
136
+ self .assertStaticSize (root , '36' )
137
+
138
+ # Check rotation for good measure
139
+ self .assertStaticRotation (root , '90' )
140
+ self .assertStaticDisplacement (root , 18 , 36 )
141
+
142
+ def testSvgMarkerUnitPixels (self ):
143
+ symbol = QgsSvgMarkerSymbolLayer ('symbols/star.svg' , 10 , 0 )
144
+ symbol .setOffset (QPointF (5 , 10 ))
145
+ symbol .setOutputUnit (QgsUnitTypes .RenderPixels )
146
+ dom , root = self .symbolToSld (symbol )
147
+ # print("Svg marker unit px: " + dom.toString())
148
+
149
+ # Check the size has not been rescaled
150
+ self .assertStaticSize (root , '10' )
151
+ self .assertStaticDisplacement (root , 5 , 10 )
152
+
153
+ def testFontMarkerUnitDefault (self ):
154
+ symbol = QgsFontMarkerSymbolLayer ('sans' , ',' , 10 , QColor ('black' ), 45 )
155
+ symbol .setOffset (QPointF (5 , 10 ))
156
+ dom , root = self .symbolToSld (symbol )
157
+ # print "Font marker unit mm: " + dom.toString()
158
+
159
+ # Check the size has been rescaled
160
+ self .assertStaticSize (root , '36' )
161
+ self .assertStaticRotation (root , '45' )
162
+ self .assertStaticDisplacement (root , 18 , 36 )
163
+
164
+ def testFontMarkerUnitPixel (self ):
165
+ symbol = QgsFontMarkerSymbolLayer ('sans' , ',' , 10 , QColor ('black' ), 45 )
166
+ symbol .setOffset (QPointF (5 , 10 ))
167
+ symbol .setOutputUnit (QgsUnitTypes .RenderPixels )
168
+ dom , root = self .symbolToSld (symbol )
169
+ # print ("Font marker unit mm: " + dom.toString())
170
+
171
+ # Check the size has been rescaled
172
+ self .assertStaticSize (root , '10' )
173
+ self .assertStaticRotation (root , '45' )
174
+ self .assertStaticDisplacement (root , 5 , 10 )
175
+
176
+ def createEllipseSymbolLayer (self ):
177
+ # No way to build it programmatically...
178
+ mTestName = 'QgsEllipseSymbolLayer'
179
+ mFilePath = QDir .toNativeSeparators (
180
+ '%s/symbol_layer/%s.sld' % (unitTestDataPath (), mTestName ))
181
+
182
+ mDoc = QDomDocument (mTestName )
183
+ mFile = QFile (mFilePath )
184
+ mFile .open (QIODevice .ReadOnly )
185
+ mDoc .setContent (mFile , True )
186
+ mFile .close ()
187
+ mSymbolLayer = QgsEllipseSymbolLayer .createFromSld (
188
+ mDoc .elementsByTagName ('PointSymbolizer' ).item (0 ).toElement ())
189
+ return mSymbolLayer
190
+
191
+ def testEllipseMarkerUnitDefault (self ):
192
+ symbol = self .createEllipseSymbolLayer ()
193
+ symbol .setOffset (QPointF (5 , 10 ))
194
+ symbol .setOutputUnit (QgsUnitTypes .RenderMillimeters )
195
+ dom , root = self .symbolToSld (symbol )
196
+ # print ("Ellipse marker unit mm: " + dom.toString())
197
+
198
+ # Check the size has been rescaled
199
+ self .assertStaticSize (root , '25' )
200
+ # Check also the stroke width
201
+ self .assertStrokeWidth (root , 2 , 4 )
202
+ self .assertStaticDisplacement (root , 18 , 36 )
203
+
204
+ def testEllipseMarkerUnitPixel (self ):
205
+ symbol = self .createEllipseSymbolLayer ()
206
+ symbol .setOffset (QPointF (5 , 10 ))
207
+ symbol .setOutputUnit (QgsUnitTypes .RenderPixels )
208
+ dom , root = self .symbolToSld (symbol )
209
+ # print ("Ellipse marker unit mm: " + dom.toString())
210
+
211
+ # Check the size has been rescaled
212
+ self .assertStaticSize (root , '7' )
213
+ # Check also the stroke width
214
+ self .assertStrokeWidth (root , 2 , 1 )
215
+ self .assertStaticDisplacement (root , 5 , 10 )
216
+
217
+ def testSimpleLineUnitDefault (self ):
218
+ symbol = QgsSimpleLineSymbolLayer (QColor ("black" ), 1 )
219
+ symbol .setCustomDashVector ([10 , 10 ])
220
+ symbol .setUseCustomDashPattern (True )
221
+ symbol .setOffset (5 )
222
+ dom , root = self .symbolToSld (symbol )
223
+
224
+ # print ("Simple line px: \n" + dom.toString())
225
+
226
+ self .assertStrokeWidth (root , 1 , 4 )
227
+ self .assertDashPattern (root , 4 , '36 36' )
228
+ self .assertStaticPerpendicularOffset (root , '18' )
229
+
230
+ def testSimpleLineUnitPixel (self ):
231
+ symbol = QgsSimpleLineSymbolLayer (QColor ("black" ), 1 )
232
+ symbol .setCustomDashVector ([10 , 10 ])
233
+ symbol .setUseCustomDashPattern (True )
234
+ symbol .setOffset (5 )
235
+ symbol .setOutputUnit (QgsUnitTypes .RenderPixels )
236
+ dom , root = self .symbolToSld (symbol )
237
+
238
+ # print ("Simple line px: \n" + dom.toString())
239
+
240
+ self .assertStrokeWidth (root , 1 , 1 )
241
+ self .assertDashPattern (root , 4 , '10 10' )
242
+ self .assertStaticPerpendicularOffset (root , '5' )
64
243
244
+ def testMarkLineUnitDefault (self ):
245
+ symbol = QgsMarkerLineSymbolLayer ()
246
+ symbol .setSubSymbol (
247
+ QgsMarkerSymbol .createSimple ({'color' : '#ffffff' , 'size' : '3' }))
248
+ symbol .setInterval (5 )
249
+ symbol .setOffset (5 )
250
+ dom , root = self .symbolToSld (symbol )
251
+
252
+ # print ("Mark line mm: \n" + dom.toString())
253
+
254
+ # size of the mark
255
+ self .assertStaticSize (root , '11' )
256
+ # gap and offset
257
+ self .assertStaticGap (root , '18' )
258
+ self .assertStaticPerpendicularOffset (root , '18' )
259
+
260
+ def testMarkLineUnitPixels (self ):
261
+ symbol = QgsMarkerLineSymbolLayer ()
262
+ symbol .setSubSymbol (
263
+ QgsMarkerSymbol .createSimple ({'color' : '#ffffff' , 'size' : '3' }))
264
+ symbol .setInterval (5 )
265
+ symbol .setOffset (5 )
266
+ symbol .setOutputUnit (QgsUnitTypes .RenderPixels )
267
+ dom , root = self .symbolToSld (symbol )
268
+
269
+ # print ("Mark line px: \n" + dom.toString())
270
+
271
+ # size of the mark
272
+ self .assertStaticSize (root , '3' )
273
+ # gap and offset
274
+ self .assertStaticGap (root , '5' )
275
+ self .assertStaticPerpendicularOffset (root , '5' )
276
+
277
+ def testSimpleFillDefault (self ):
278
+ symbol = QgsSimpleFillSymbolLayer (
279
+ QColor ('red' ), Qt .SolidPattern , QColor ('green' ), Qt .SolidLine , 5 )
280
+ symbol .setOffset (QPointF (5 , 10 ))
281
+
282
+ dom , root = self .symbolToSld (symbol )
283
+
284
+ # print ("Simple fill mm: \n" + dom.toString())
285
+
286
+ self .assertStrokeWidth (root , 2 , 18 )
287
+ self .assertStaticDisplacement (root , 18 , 36 )
288
+
289
+ def testSimpleFillPixels (self ):
290
+ symbol = QgsSimpleFillSymbolLayer (
291
+ QColor ('red' ), Qt .SolidPattern , QColor ('green' ), Qt .SolidLine , 5 )
292
+ symbol .setOffset (QPointF (5 , 10 ))
293
+ symbol .setOutputUnit (QgsUnitTypes .RenderPixels )
294
+
295
+ dom , root = self .symbolToSld (symbol )
296
+ # print ( "Simple fill px: \n" + dom.toString())
297
+
298
+ self .assertStrokeWidth (root , 2 , 5 )
299
+ self .assertStaticDisplacement (root , 5 , 10 )
300
+
301
+ def testSvgFillDefault (self ):
302
+ symbol = QgsSVGFillSymbolLayer ('test/star.svg' , 10 , 45 )
303
+ symbol .setSvgOutlineWidth (3 )
304
+
305
+ dom , root = self .symbolToSld (symbol )
306
+ # print ("Svg fill mm: \n" + dom.toString())
307
+
308
+ self .assertStaticRotation (root , '45' )
309
+ self .assertStaticSize (root , '36' )
310
+ # width of the svg outline
311
+ self .assertStrokeWidth (root , 1 , 11 )
312
+ # width of the polygon outline
313
+ self .assertStrokeWidth (root , 3 , 1 )
314
+
315
+ def testSvgFillPixel (self ):
316
+ symbol = QgsSVGFillSymbolLayer ('test/star.svg' , 10 , 45 )
317
+ symbol .setSvgOutlineWidth (3 )
318
+ symbol .setOutputUnit (QgsUnitTypes .RenderPixels )
319
+
320
+ dom , root = self .symbolToSld (symbol )
321
+ # print ("Svg fill px: \n" + dom.toString())
322
+
323
+ self .assertStaticRotation (root , '45' )
324
+ self .assertStaticSize (root , '10' )
325
+ # width of the svg outline
326
+ self .assertStrokeWidth (root , 1 , 3 )
327
+ # width of the polygon outline
328
+ self .assertStrokeWidth (root , 3 , 0.26 )
329
+
330
+ def testLineFillDefault (self ):
331
+ symbol = QgsLinePatternFillSymbolLayer ()
332
+ symbol .setLineAngle (45 )
333
+ symbol .setLineWidth (1 )
334
+ symbol .setOffset (5 )
335
+
336
+ dom , root = self .symbolToSld (symbol )
337
+ # print ("Line fill mm: \n" + dom.toString())
338
+
339
+ self .assertStaticRotation (root , '45' )
340
+ self .assertStrokeWidth (root , 1 , 4 )
341
+ self .assertStaticSize (root , '18' )
342
+ self .assertStaticDisplacement (root , 15 , 9 )
343
+
344
+ def testLineFillPixels (self ):
345
+ symbol = QgsLinePatternFillSymbolLayer ()
346
+ symbol .setLineAngle (45 )
347
+ symbol .setLineWidth (1 )
348
+ symbol .setOffset (5 )
349
+ symbol .setOutputUnit (QgsUnitTypes .RenderPixels )
350
+
351
+ dom , root = self .symbolToSld (symbol )
352
+ # print ("Line fill px: \n" + dom.toString())
353
+
354
+ self .assertStaticRotation (root , '45' )
355
+ self .assertStrokeWidth (root , 1 , 1 )
356
+ self .assertStaticSize (root , '5' )
357
+ self .assertStaticDisplacement (root , 4.25 , 2.63 )
358
+
359
+ def testPointFillDefault (self ):
360
+ symbol = QgsPointPatternFillSymbolLayer ()
361
+ dom , root = self .symbolToSld (symbol )
362
+ # print ("Point fill mm: \n" + dom.toString())
363
+
364
+ self .assertStaticSize (root , '7' )
365
+
366
+ def testPointFillpixels (self ):
367
+ symbol = QgsPointPatternFillSymbolLayer ()
368
+ symbol .setOutputUnit (QgsUnitTypes .RenderPixels )
369
+ dom , root = self .symbolToSld (symbol )
370
+ # print ("Point fill px: \n" + dom.toString())
371
+
372
+ self .assertStaticSize (root , '2' )
373
+
374
+ def assertDashPattern (self , root , svgParameterIdx , expectedPattern ):
375
+ strokeWidth = root .elementsByTagName (
376
+ 'se:SvgParameter' ).item (svgParameterIdx )
377
+ svgParameterName = strokeWidth .attributes ().namedItem ('name' )
378
+ self .assertEquals ("stroke-dasharray" , svgParameterName .nodeValue ())
379
+ self .assertEquals (
380
+ expectedPattern , strokeWidth .firstChild ().nodeValue ())
381
+
382
+ def assertStaticGap (self , root , expectedValue ):
383
+ # Check the rotation element is a literal, not a
384
+ rotation = root .elementsByTagName ('se:Gap' ).item (0 )
385
+ literal = rotation .firstChild ()
386
+ self .assertEquals ("ogc:Literal" , literal .nodeName ())
387
+ self .assertEquals (expectedValue , literal .firstChild ().nodeValue ())
388
+
389
+ def assertStaticSize (self , root , expectedValue ):
390
+ size = root .elementsByTagName ('se:Size' ).item (0 )
391
+ self .assertEquals (expectedValue , size .firstChild ().nodeValue ())
392
+
393
+ def assertStaticPerpendicularOffset (self , root , expectedValue ):
394
+ offset = root .elementsByTagName ('se:PerpendicularOffset' ).item (0 )
395
+ self .assertEquals (expectedValue , offset .firstChild ().nodeValue ())
396
+
397
+ def symbolToSld (self , symbolLayer ):
398
+ dom = QDomDocument ()
399
+ root = dom .createElement ("FakeRoot" )
400
+ dom .appendChild (root )
401
+ symbolLayer .toSld (dom , root , {})
402
+ return dom , root
65
403
66
404
if __name__ == '__main__' :
67
405
unittest .main ()
0 commit comments