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
+ QgsUnitTypes ,
35
+ QgsPoint ,
36
+ QgsSvgMarkerSymbolLayer ,
37
+ QgsEllipseSymbolLayer ,
38
+ QgsSimpleFillSymbolLayer ,
39
+ QgsSVGFillSymbolLayer ,
40
+ QgsSvgMarkerSymbolLayer ,
41
+ QgsLinePatternFillSymbolLayer ,
42
+ QgsSimpleLineSymbolLayer ,
43
+ QgsMarkerLineSymbolLayer ,
44
+ QgsSimpleMarkerSymbolLayer ,
45
+ QgsFontMarkerSymbolLayer
34
46
)
35
47
from qgis .testing .mocked import get_iface
36
48
from utilities import unitTestDataPath
@@ -51,6 +63,28 @@ def createLayerWithOneLine():
51
63
return linelayer
52
64
53
65
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
+
54
88
class TestQgsSymbolLayerReadSld (unittest .TestCase ):
55
89
56
90
"""
@@ -111,6 +145,264 @@ def testSimpleMarkerRotation(self):
111
145
props = layer .renderer ().symbol ().symbolLayers ()[0 ].properties ()
112
146
self .assertEqual (props ['angle' ], '50' )
113
147
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
+
114
406
115
407
if __name__ == '__main__' :
116
408
unittest .main ()
0 commit comments