26
26
import qgis # NOQA
27
27
28
28
import os
29
+ from qgis .PyQt .QtXml import QDomDocument
29
30
from qgis .testing import start_app , unittest
30
31
from qgis .core import (QgsVectorLayer ,
31
32
QgsFeature ,
32
33
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
34
47
)
35
48
from qgis .testing import unittest
36
49
from qgis .testing .mocked import get_iface
@@ -52,6 +65,28 @@ def createLayerWithOneLine():
52
65
return linelayer
53
66
54
67
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
+
55
90
class TestQgsSymbolLayerReadSld (unittest .TestCase ):
56
91
57
92
"""
@@ -70,17 +105,17 @@ def test_Literal_within_CSSParameter(self):
70
105
props = layer .rendererV2 ().symbol ().symbolLayers ()[0 ].properties ()
71
106
72
107
def testLineColor ():
73
- # stroke CSSParameter within ogc:Literal
108
+ # border CSSParameter within ogc:Literal
74
109
# expected color is #003EBA, RGB 0,62,186
75
110
self .assertEqual (layer .rendererV2 ().symbol ().symbolLayers ()[0 ].color ().name (), '#003eba' )
76
111
77
112
def testLineWidth ():
78
- # stroke -width CSSParameter within ogc:Literal
113
+ # border -width CSSParameter within ogc:Literal
79
114
self .assertEqual (props ['line_width' ], '2' )
80
115
81
116
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
84
119
self .assertEqual (props ['line_color' ], '0,62,186,25' )
85
120
86
121
testLineColor ()
@@ -112,6 +147,265 @@ def testSimpleMarkerRotation(self):
112
147
props = layer .rendererV2 ().symbol ().symbolLayers ()[0 ].properties ()
113
148
self .assertEqual (props ['angle' ], '50' )
114
149
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
+
115
409
116
410
if __name__ == '__main__' :
117
411
unittest .main ()
0 commit comments