30
30
import re
31
31
import yaml
32
32
import hashlib
33
+ import ast
33
34
34
35
from osgeo import gdal
35
36
from osgeo .gdalconst import GA_ReadOnly
36
37
37
38
from numpy import nan_to_num
38
39
39
40
from qgis .core import (QgsApplication ,
40
- QgsProcessingParameterDefinition )
41
+ QgsProcessing ,
42
+ QgsProcessingParameterDefinition ,
43
+ QgsProcessingParameterBoolean ,
44
+ QgsProcessingParameterNumber ,
45
+ QgsProcessingParameterFile ,
46
+ QgsProcessingParameterString ,
47
+ QgsProcessingParameterVectorLayer ,
48
+ QgsProcessingParameterFeatureSource ,
49
+ QgsProcessingParameterRasterLayer ,
50
+ QgsProcessingParameterMultipleLayers ,
51
+ QgsProcessingParameterRasterDestination ,
52
+ QgsProcessingParameterFeatureSink ,
53
+ QgsProcessingParameterVectorDestination ,
54
+ QgsProcessingParameterFileDestination )
41
55
from qgis .PyQt .QtCore import QCoreApplication , QMetaObject
42
56
from qgis .PyQt .QtWidgets import QDialog , QVBoxLayout , QTextEdit , QMessageBox
43
57
44
- from processing .core .Processing import Processing
45
- from processing .core .outputs import (
46
- OutputNumber ,
47
- OutputString ,
48
- OutputRaster ,
49
- OutputVector ,
50
- OutputHTML ,
51
- OutputFile
52
- )
53
-
54
- from processing .core .parameters import (
55
- ParameterRaster ,
56
- ParameterVector ,
57
- ParameterMultipleInput ,
58
- ParameterFile ,
59
- ParameterString ,
60
- ParameterNumber ,
61
- ParameterBoolean ,
62
- ParameterTable
63
- )
64
-
65
58
66
59
def extractSchemaPath (filepath ):
67
60
"""
@@ -132,15 +125,24 @@ def parseParameters(command):
132
125
pos = m .end (0 )
133
126
134
127
128
+ def splitAlgIdAndParameters (command ):
129
+ """
130
+ Extracts the algorithm ID and input parameter list from a processing runalg command
131
+ """
132
+ exp = re .compile (r"""['"](.*?)['"]\s*,\s*(.*)""" )
133
+ m = exp .search (command [len ('processing.run(' ):- 1 ])
134
+ return m .group (1 ), ast .literal_eval (m .group (2 ))
135
+
136
+
135
137
def createTest (text ):
136
138
definition = {}
137
139
138
- tokens = list ( parseParameters ( text [ len ( 'processing.run(' ): - 1 ]) )
139
- cmdname = tokens [ 0 ]
140
- alg = QgsApplication .processingRegistry ().createAlgorithmById (cmdname )
140
+ alg_id , parameters = splitAlgIdAndParameters ( text )
141
+
142
+ alg = QgsApplication .processingRegistry ().createAlgorithmById (alg_id )
141
143
142
- definition ['name' ] = 'Test ({})' .format (cmdname )
143
- definition ['algorithm' ] = cmdname
144
+ definition ['name' ] = 'Test ({})' .format (alg_id )
145
+ definition ['algorithm' ] = alg_id
144
146
145
147
params = {}
146
148
results = {}
@@ -151,12 +153,12 @@ def createTest(text):
151
153
continue
152
154
153
155
i += 1
154
- token = tokens [ i ]
156
+ token = parameters [ param . name () ]
155
157
# Handle empty parameters that are optionals
156
158
if param .flags () & QgsProcessingParameterDefinition .FlagOptional and token is None :
157
159
continue
158
160
159
- if isinstance (param , ParameterVector ):
161
+ if isinstance (param , ( QgsProcessingParameterVectorLayer , QgsProcessingParameterFeatureSource ) ):
160
162
schema , filepath = extractSchemaPath (token )
161
163
p = {
162
164
'type' : 'vector' ,
@@ -166,7 +168,7 @@ def createTest(text):
166
168
p ['location' ] = '[The source data is not in the testdata directory. Please use data in the processing/tests/testdata folder.]'
167
169
168
170
params [param .name ()] = p
169
- elif isinstance (param , ParameterRaster ):
171
+ elif isinstance (param , QgsProcessingParameterRasterLayer ):
170
172
schema , filepath = extractSchemaPath (token )
171
173
p = {
172
174
'type' : 'raster' ,
@@ -176,27 +178,18 @@ def createTest(text):
176
178
p ['location' ] = '[The source data is not in the testdata directory. Please use data in the processing/tests/testdata folder.]'
177
179
178
180
params [param .name ()] = p
179
- elif isinstance (param , ParameterTable ):
180
- schema , filepath = extractSchemaPath (token )
181
- p = {
182
- 'type' : 'table' ,
183
- 'name' : filepath
184
- }
185
- if not schema :
186
- p ['location' ] = '[The source data is not in the testdata directory. Please use data in the processing/tests/testdata folder.]'
187
-
188
- params [param .name ()] = p
189
- elif isinstance (param , ParameterMultipleInput ):
181
+ elif isinstance (param , QgsProcessingParameterMultipleLayers ):
190
182
multiparams = token .split (';' )
191
183
newparam = []
192
184
193
185
# Handle datatype detection
194
- dataType = param .dataType ()
195
- if dataType in ['points' , 'lines' , 'polygons' , 'any vectors' ]:
186
+ dataType = param .layerType ()
187
+ if dataType in [QgsProcessing . TypeVectorAny , QgsProcessing . TypeVectorPoint , QgsProcessing . TypeVectorLine , QgsProcessing . TypeVectorPolygon , QgsProcessing . TypeTable ]:
196
188
dataType = 'vector'
197
189
else :
198
190
dataType = 'raster'
199
191
192
+ schema = None
200
193
for mp in multiparams :
201
194
schema , filepath = extractSchemaPath (mp )
202
195
newparam .append ({
@@ -211,7 +204,7 @@ def createTest(text):
211
204
p ['location' ] = '[The source data is not in the testdata directory. Please use data in the processing/tests/testdata folder.]'
212
205
213
206
params [param .name ()] = p
214
- elif isinstance (param , ParameterFile ):
207
+ elif isinstance (param , QgsProcessingParameterFile ):
215
208
schema , filepath = extractSchemaPath (token )
216
209
p = {
217
210
'type' : 'file' ,
@@ -221,12 +214,12 @@ def createTest(text):
221
214
p ['location' ] = '[The source data is not in the testdata directory. Please use data in the processing/tests/testdata folder.]'
222
215
223
216
params [param .name ()] = p
224
- elif isinstance (param , ParameterString ):
217
+ elif isinstance (param , QgsProcessingParameterString ):
225
218
params [param .name ()] = token
226
- elif isinstance (param , ParameterBoolean ):
219
+ elif isinstance (param , QgsProcessingParameterBoolean ):
227
220
params [param .name ()] = token
228
- elif isinstance (param , ParameterNumber ):
229
- if param .isInteger :
221
+ elif isinstance (param , QgsProcessingParameterNumber ):
222
+ if param .dataType () == QgsProcessingParameterNumber . Integer :
230
223
params [param .name ()] = int (token )
231
224
else :
232
225
params [param .name ()] = float (token )
@@ -235,16 +228,14 @@ def createTest(text):
235
228
token = token [1 :]
236
229
if token [- 1 ] == '"' :
237
230
token = token [:- 1 ]
238
- params [param .name ] = token
231
+ params [param .name () ] = token
239
232
240
233
definition ['params' ] = params
241
234
242
235
for i , out in enumerate ([out for out in alg .destinationParameterDefinitions () if not out .flags () & QgsProcessingParameterDefinition .FlagHidden ]):
243
- token = tokens [ i - len ( alg . destinationParameterDefinitions () )]
236
+ token = parameters [ out . name ( )]
244
237
245
- if isinstance (out , (OutputNumber , OutputString )):
246
- results [out .name ] = str (out )
247
- elif isinstance (out , OutputRaster ):
238
+ if isinstance (out , QgsProcessingParameterRasterDestination ):
248
239
if token is None :
249
240
QMessageBox .warning (None ,
250
241
tr ('Error' ),
@@ -258,26 +249,26 @@ def createTest(text):
258
249
dataArray = nan_to_num (dataset .ReadAsArray (0 ))
259
250
strhash = hashlib .sha224 (dataArray .data ).hexdigest ()
260
251
261
- results [out .name ] = {
252
+ results [out .name () ] = {
262
253
'type' : 'rasterhash' ,
263
254
'hash' : strhash
264
255
}
265
- elif isinstance (out , OutputVector ):
256
+ elif isinstance (out , ( QgsProcessingParameterVectorDestination , QgsProcessingParameterFeatureSink ) ):
266
257
schema , filepath = extractSchemaPath (token )
267
- results [out .name ] = {
258
+ results [out .name () ] = {
268
259
'type' : 'vector' ,
269
260
'name' : filepath
270
261
}
271
262
if not schema :
272
- results [out .name ]['location' ] = '[The expected result data is not in the testdata directory. Please write it to processing/tests/testdata/expected. Prefer gml files.]'
273
- elif isinstance (out , OutputHTML ) or isinstance ( out , OutputFile ):
263
+ results [out .name () ]['location' ] = '[The expected result data is not in the testdata directory. Please write it to processing/tests/testdata/expected. Prefer gml files.]'
264
+ elif isinstance (out , QgsProcessingParameterFileDestination ):
274
265
schema , filepath = extractSchemaPath (token )
275
- results [out .name ] = {
266
+ results [out .name () ] = {
276
267
'type' : 'file' ,
277
268
'name' : filepath
278
269
}
279
270
if not schema :
280
- results [out .name ]['location' ] = '[The expected result file is not in the testdata directory. Please redirect the output to processing/tests/testdata/expected.]'
271
+ results [out .name () ]['location' ] = '[The expected result file is not in the testdata directory. Please redirect the output to processing/tests/testdata/expected.]'
281
272
282
273
definition ['results' ] = results
283
274
dlg = ShowTestDialog (yaml .dump ([definition ], default_flow_style = False ))
0 commit comments