Skip to content

Commit 065b357

Browse files
committedApr 13, 2013
[sextante] several fixes for supporting optional parameters in modeler
1 parent 3b205d3 commit 065b357

File tree

12 files changed

+140
-43
lines changed

12 files changed

+140
-43
lines changed
 

‎python/plugins/sextante/algs/ftools/ConvexHull.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def defineCharacteristics(self):
5959
self.name = "Convex hull"
6060
self.group = "Vector geometry tools"
6161
self.addParameter(ParameterVector(ConvexHull.INPUT, "Input layer", ParameterVector.VECTOR_TYPE_ANY))
62-
self.addParameter(ParameterTableField(ConvexHull.FIELD, "Field", ConvexHull.INPUT))
62+
self.addParameter(ParameterTableField(ConvexHull.FIELD, "Field (optional, only used if creating convex hulls by classes)", ConvexHull.INPUT, optional = True))
6363
self.addParameter(ParameterSelection(ConvexHull.METHOD, "Method", ConvexHull.METHODS))
6464
self.addOutput(OutputVector(ConvexHull.OUTPUT, "Convex hull"))
6565

@@ -71,22 +71,23 @@ def processAlgorithm(self, progress):
7171
GEOS_EXCEPT = True
7272
FEATURE_EXCEPT = True
7373

74-
index = layer.fieldNameIndex(fieldName)
75-
fType = layer.pendingFields()[index].type()
74+
7675
f = QgsField("value")
7776
f.setType(QVariant.String)
7877
f.setLength(255)
7978
if useField:
80-
if fType == QVariant.Int:
81-
f.setType(QVariant.Int)
82-
f.setLength(20)
83-
elif fType == QVariant.Double:
84-
f.setType(QVariant.Double)
85-
f.setLength(20)
86-
f.setPrecision(6)
87-
else:
88-
f.setType(QVariant.String)
89-
f.setLength(255)
79+
index = layer.fieldNameIndex(fieldName)
80+
fType = layer.pendingFields()[index].type()
81+
if fType == QVariant.Int:
82+
f.setType(QVariant.Int)
83+
f.setLength(20)
84+
elif fType == QVariant.Double:
85+
f.setType(QVariant.Double)
86+
f.setLength(20)
87+
f.setPrecision(6)
88+
else:
89+
f.setType(QVariant.String)
90+
f.setLength(255)
9091

9192
fields = [QgsField("id", QVariant.Int, "", 20),
9293
f,

‎python/plugins/sextante/core/Sextante.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,6 @@ def runAlgorithm(algOrName, onFinish, *args):
268268
return
269269
else:
270270
i = 0
271-
272-
settrace()
273271
for param in alg.parameters:
274272
if not param.hidden:
275273
if not param.setValue(args[i]):

‎python/plugins/sextante/modeler/ModelerAlgorithm.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -409,11 +409,11 @@ def prepareAlgorithm(self, alg, iAlg):
409409
aap = self.algParameters[iAlg][param.name]
410410
if aap == None:
411411
if isinstance(param, ParameterExtent):
412-
value = self.getValueFromAlgorithmAndParameter(aap)
413-
if value is None:
414-
value = self.getMinCoveringExtent()
412+
value = self.getMinCoveringExtent()
415413
if not param.setValue(value):
416414
raise GeoAlgorithmExecutionException("Wrong value: " + str(value))
415+
else:
416+
param.setValue(None)
417417
continue
418418
if isinstance(param, ParameterMultipleInput):
419419
value = self.getValueFromAlgorithmAndParameter(aap)

‎python/plugins/sextante/modeler/ModelerParametersDialog.py

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ def getWidgetFromParameter(self, param):
418418
elif isinstance(param, ParameterString):
419419
strings = self.getStrings()
420420
if param.multiline:
421-
item = MultilineTextPanel(strings)
421+
item = MultilineTextPanel(strings,self.model)
422422
item.setText(str(param.default))
423423
else:
424424
item = QtGui.QComboBox()
@@ -597,6 +597,7 @@ def setParamValues(self):
597597

598598
params = self.alg.parameters
599599
outputs = self.alg.outputs
600+
600601
for param in params:
601602
if param.hidden:
602603
continue
@@ -650,12 +651,16 @@ def setParamTableFieldValue(self, param, widget):
650651
idx = widget.findText(widget.currentText())
651652
if idx < 0:
652653
name = self.getSafeNameForHarcodedParameter(param)
653-
value = AlgorithmAndParameter(AlgorithmAndParameter.PARENT_MODEL_ALGORITHM, name)
654-
self.params[param.name] = value
655-
value = str(widget.currentText()).strip()
656-
if value == "":
657-
return False
654+
value = AlgorithmAndParameter(AlgorithmAndParameter.PARENT_MODEL_ALGORITHM, name)
655+
s = str(widget.currentText()).strip()
656+
if s == "":
657+
if param.optional:
658+
self.params[param.name] = None
659+
return True
660+
else:
661+
return False
658662
else:
663+
self.params[param.name] = value
659664
self.values[name] = str(widget.currentText())
660665
return True
661666
else:
@@ -664,16 +669,22 @@ def setParamTableFieldValue(self, param, widget):
664669
return True
665670

666671
def setParamStringValue(self, param, widget):
667-
if param.multiline:
668-
option = widget.getOption()
672+
if param.multiline:
673+
name = self.getSafeNameForHarcodedParameter(param)
674+
paramValue = AlgorithmAndParameter(AlgorithmAndParameter.PARENT_MODEL_ALGORITHM, name)
669675
value = widget.getValue()
670-
if option == MultilineTextPanel.USE_TEXT:
676+
option = widget.getOption()
677+
if option == MultilineTextPanel.USE_TEXT:
671678
if value == "":
672-
return False
673-
name = self.getSafeNameForHarcodedParameter(param)
674-
self.values[name] = value
675-
paramValue = AlgorithmAndParameter(AlgorithmAndParameter.PARENT_MODEL_ALGORITHM, name)
676-
self.params[param.name] = paramValue
679+
if param.optional:
680+
self.params[param.name] = None
681+
return True
682+
else:
683+
return False
684+
else:
685+
self.values[name] = value
686+
687+
self.params[param.name] = paramValue
677688
else:
678689
self.params[param.name] = value
679690
else:
@@ -684,7 +695,15 @@ def setParamStringValue(self, param, widget):
684695
name = self.getSafeNameForHarcodedParameter(param)
685696
value = AlgorithmAndParameter(AlgorithmAndParameter.PARENT_MODEL_ALGORITHM, name)
686697
self.params[param.name] = value
687-
self.values[name] = str(widget.currentText())
698+
value = str(widget.currentText()).strip()
699+
if value == "":
700+
if param.optional:
701+
self.values[name] = None
702+
return True
703+
else:
704+
return False
705+
else:
706+
self.values[name] = str(widget.currentText())
688707
else:
689708
value = widget.itemData(widget.currentIndex()).toPyObject()
690709
self.params[param.name] = value

‎python/plugins/sextante/modeler/MultilineTextPanel.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,10 @@ class MultilineTextPanel(QtGui.QWidget):
3434

3535
USE_TEXT = 0
3636

37-
def __init__(self, options, parent = None):
37+
def __init__(self, options, model, parent = None):
3838
super(MultilineTextPanel, self).__init__(parent)
3939
self.options = options
40+
self.model = model
4041
self.verticalLayout = QtGui.QVBoxLayout(self)
4142
self.verticalLayout.setSpacing(2)
4243
self.verticalLayout.setMargin(0)
@@ -71,7 +72,7 @@ def setValue(self, value):
7172
if item.alg == value.alg and item.param == value.param:
7273
self.combo.setCurrentIndex(idx)
7374
return
74-
self.combo.setCurrentIndex(idx)
75+
self.combo.setCurrentIndex(0)
7576
value = self.model.getValueFromAlgorithmAndParameter(value)
7677
if value:
7778
self.textBox.setPlainText(str(value))
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
NAME:A model with an empty string
2+
GROUP:[Test models]
3+
PARAMETER:ParameterVector|VECTORLAYER_V|v|-1|False
4+
120.0,60.0
5+
VALUE:HARDCODEDPARAMVALUE_FORMULA_0===value = 10
6+
VALUE:HARDCODEDPARAMVALUE_FIELD_PRECISION_0===0
7+
VALUE:HARDCODEDPARAMVALUE_FIELD_TYPE_0===0
8+
VALUE:HARDCODEDPARAMVALUE_FIELD_LENGTH_0===10
9+
VALUE:HARDCODEDPARAMVALUE_FIELD_NAME_0===NewField
10+
ALGORITHM:qgis:advancedpythonfieldcalculator
11+
120.0,160.0
12+
None
13+
-1|VECTORLAYER_V
14+
-1|HARDCODEDPARAMVALUE_FIELD_NAME_0
15+
-1|HARDCODEDPARAMVALUE_FIELD_TYPE_0
16+
-1|HARDCODEDPARAMVALUE_FIELD_LENGTH_0
17+
-1|HARDCODEDPARAMVALUE_FIELD_PRECISION_0
18+
None
19+
-1|HARDCODEDPARAMVALUE_FORMULA_0
20+
out
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
NAME:A model with an optional field
2+
GROUP:[Test models]
3+
PARAMETER:ParameterVector|VECTORLAYER_V|v|-1|False
4+
120.0,60.0
5+
VALUE:HARDCODEDPARAMVALUE_METHOD_0===0
6+
ALGORITHM:qgis:convexhull
7+
135.0,186.0
8+
None
9+
-1|VECTORLAYER_V
10+
None
11+
-1|HARDCODEDPARAMVALUE_METHOD_0
12+
result

‎python/plugins/sextante/parameters/ParameterExtent.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,13 @@ def setValue(self, text):
3939
self.value = self.default
4040
return True
4141
tokens = text.split(",")
42-
if len(tokens)!= 5:
42+
if len(tokens)!= 4:
4343
return False
4444
try:
45-
n1 = float(tokens[1])
46-
n2 = float(tokens[2])
47-
n3 = float(tokens[3])
48-
n4 = float(tokens[4])
45+
n1 = float(tokens[0])
46+
n2 = float(tokens[1])
47+
n3 = float(tokens[2])
48+
n4 = float(tokens[3])
4949
self.value=text
5050
return True
5151
except:
@@ -60,5 +60,5 @@ def serialize(self):
6060

6161
def deserialize(self, s):
6262
tokens = s.split("|")
63-
return ParameterExtent(tokens[0], tokens[1], tokens[2])
63+
return ParameterExtent(tokens[1], tokens[2], tokens[3])
6464

‎python/plugins/sextante/parameters/ParameterString.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ def __init__(self, name="", description="", default="", multiline = False, optio
3535
self.default = default
3636
self.value = None
3737
self.multiline = multiline
38+
self.optional = optional
3839

3940
def setValue(self, obj):
4041
if obj is None:

‎python/plugins/sextante/parameters/ParameterTableField.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ def __init__(self, name="", description="", parent=None, datatype=-1, optional=F
3636
self.parent = parent
3737
self.value = None
3838
self.datatype = datatype
39+
self.optional= optional
3940

4041
def getValueAsCommandLineParameter(self):
4142
return "\"" + str(self.value) + "\""
@@ -44,7 +45,9 @@ def getAsScriptCode(self):
4445
return "##" + self.name + "=field " + str(self.parent)
4546

4647
def setValue(self, field):
47-
if len(field) > 0:
48+
if field is None:
49+
return self.optional
50+
elif len(field) > 0:
4851
self.value = str(field)
4952
else:
5053
return self.optional

‎python/plugins/sextante/tests/ModelerAlgorithmTest.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,48 @@ def test_modelernotinorder(self):
121121
dataset=gdal.Open(output, GA_ReadOnly)
122122
strhash=hash(str(dataset.ReadAsArray(0).tolist()))
123123
self.assertEqual(strhash,-1557050506)
124+
125+
def test_modeleroptionalfield(self):
126+
outputs=sextante.runalg("modeler:optionalfield",points(),None)
127+
output=outputs['OUTPUT_ALG0']
128+
layer=QGisLayers.getObjectFromUri(output, True)
129+
fields=layer.pendingFields()
130+
expectednames=['id','value','area','perim']
131+
expectedtypes=['Integer','String','Real','Real']
132+
names=[str(f.name()) for f in fields]
133+
types=[str(f.typeName()) for f in fields]
134+
self.assertEqual(expectednames, names)
135+
self.assertEqual(expectedtypes, types)
136+
features=sextante.getfeatures(layer)
137+
self.assertEqual(1, len(features))
138+
feature=features.next()
139+
attrs=feature.attributes()
140+
expectedvalues=["0","all","3592.818848","230.989919"]
141+
values=[str(attr.toString()) for attr in attrs]
142+
self.assertEqual(expectedvalues, values)
143+
wkt='POLYGON((270839.46818665 4458921.97813894,270778.60197966 4458935.96883677,270786.54279065 4458980.04784113,270803.15756434 4458983.84880322,270839.65586926 4458983.16267036,270855.74530134 4458940.79948673,270839.46818665 4458921.97813894))'
144+
self.assertEqual(wkt, str(feature.geometry().exportToWkt()))
145+
146+
def test_modeleremptystring(self):
147+
outputs=sextante.runalg("modeler:emptystring",union(),None)
148+
output=outputs['OUTPUT_LAYER_ALG0']
149+
layer=QGisLayers.getObjectFromUri(output, True)
150+
fields=layer.pendingFields()
151+
expectednames=['ID','POLY_NUM_A','POLY_ST_A','ID_2','POLY_NUM_B','POLY_ST_B','NewField']
152+
expectedtypes=['Integer','Real','String','Integer','Real','String','Integer']
153+
names=[str(f.name()) for f in fields]
154+
types=[str(f.typeName()) for f in fields]
155+
self.assertEqual(expectednames, names)
156+
self.assertEqual(expectedtypes, types)
157+
features=sextante.getfeatures(layer)
158+
self.assertEqual(8, len(features))
159+
feature=features.next()
160+
attrs=feature.attributes()
161+
expectedvalues=["1","1.1","string a","2","1","string a","10"]
162+
values=[str(attr.toString()) for attr in attrs]
163+
self.assertEqual(expectedvalues, values)
164+
wkt='POLYGON((270807.08580285 4458940.1594565,270798.42294527 4458914.62661676,270780.81854858 4458914.21983449,270763.52289518 4458920.715993,270760.3449542 4458926.6570575,270763.78234766 4458958.22561242,270794.30290024 4458942.16424502,270807.08580285 4458940.1594565))'
165+
self.assertEqual(wkt, str(feature.geometry().exportToWkt()))
124166

125167

126168
def suite():

‎python/plugins/sextante/tests/QgisAlgsTest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ def test_qgiscreategrid(self):
142142
self.assertEqual(wkt, str(feature.geometry().exportToWkt()))
143143

144144
def test_qgiscreategridnointeger(self):
145-
outputs=sextante.runalg("qgis:creategrid",0.1,0.1,1,1,0,0,None)
145+
outputs=sextante.runalg("qgis:creategrid",0.1,0.1,1,1,0,0,0,None)
146146
output=outputs['SAVENAME']
147147
layer=QGisLayers.getObjectFromUri(output, True)
148148
fields=layer.pendingFields()

0 commit comments

Comments
 (0)
Please sign in to comment.