Skip to content

Commit 4c52607

Browse files
authoredAug 21, 2017
Merge pull request #5050 from nyalldawson/algs
Port more QGIS algs to new API
2 parents 2530d9e + bcc6627 commit 4c52607

27 files changed

+995
-756
lines changed
 

‎python/plugins/processing/algs/qgis/DefineProjection.py

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,12 @@
2828
import os
2929
import re
3030

31-
from qgis.core import (QgsCoordinateReferenceSystem,
32-
QgsApplication,
33-
QgsProcessingUtils)
34-
from qgis.utils import iface
31+
from qgis.core import (QgsProcessing,
32+
QgsProcessingParameterVectorLayer,
33+
QgsProcessingParameterCrs,
34+
QgsProcessingOutputVectorLayer)
3535

3636
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
37-
from processing.core.parameters import ParameterVector
38-
from processing.core.parameters import ParameterCrs
39-
from processing.core.outputs import OutputVector
4037

4138
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
4239

@@ -45,7 +42,6 @@ class DefineProjection(QgisAlgorithm):
4542

4643
INPUT = 'INPUT'
4744
CRS = 'CRS'
48-
OUTPUT = 'OUTPUT'
4945

5046
def group(self):
5147
return self.tr('Vector general tools')
@@ -54,11 +50,11 @@ def __init__(self):
5450
super().__init__()
5551

5652
def initAlgorithm(self, config=None):
57-
self.addParameter(ParameterVector(self.INPUT,
58-
self.tr('Input Layer')))
59-
self.addParameter(ParameterCrs(self.CRS, 'Output CRS'))
60-
self.addOutput(OutputVector(self.OUTPUT,
61-
self.tr('Layer with projection'), True))
53+
self.addParameter(QgsProcessingParameterVectorLayer(self.INPUT,
54+
self.tr('Input Layer'), types=[QgsProcessing.TypeVectorAnyGeometry]))
55+
self.addParameter(QgsProcessingParameterCrs(self.CRS, 'Output CRS'))
56+
self.addOutput(QgsProcessingOutputVectorLayer(self.INPUT,
57+
self.tr('Layer with projection')))
6258

6359
def name(self):
6460
return 'definecurrentprojection'
@@ -67,9 +63,8 @@ def displayName(self):
6763
return self.tr('Define current projection')
6864

6965
def processAlgorithm(self, parameters, context, feedback):
70-
fileName = self.getParameterValue(self.INPUT)
71-
layer = QgsProcessingUtils.mapLayerFromString(fileName, context)
72-
crs = QgsCoordinateReferenceSystem(self.getParameterValue(self.CRS))
66+
layer = self.parameterAsVectorLayer(parameters, self.INPUT, context)
67+
crs = self.parameterAsCrs(parameters, self.CRS, context)
7368

7469
provider = layer.dataProvider()
7570
ds = provider.dataSourceUri()
@@ -89,6 +84,6 @@ def processAlgorithm(self, parameters, context, feedback):
8984
f.write(wkt)
9085

9186
layer.setCrs(crs)
92-
iface.mapCanvas().refresh()
87+
layer.triggerRepaint()
9388

94-
self.setOutputValue(self.OUTPUT, fileName)
89+
return {self.INPUT: layer}

‎python/plugins/processing/algs/qgis/ExecuteSQL.py

Lines changed: 44 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,18 @@
2525

2626
__revision__ = '$Format:%H$'
2727

28-
from qgis.core import (QgsFeature,
29-
QgsVirtualLayerDefinition,
28+
from qgis.core import (QgsVirtualLayerDefinition,
3029
QgsVectorLayer,
31-
QgsCoordinateReferenceSystem,
3230
QgsWkbTypes,
33-
QgsApplication,
34-
QgsProcessingUtils)
31+
QgsProcessingParameterMultipleLayers,
32+
QgsProcessingParameterString,
33+
QgsProcessingParameterEnum,
34+
QgsProcessingParameterCrs,
35+
QgsProcessingParameterFeatureSink,
36+
QgsFeatureSink,
37+
QgsProcessingException)
3538

3639
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
37-
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
38-
from processing.core.parameters import ParameterString
39-
from processing.core.parameters import ParameterMultipleInput
40-
from processing.core.parameters import ParameterCrs
41-
from processing.core.parameters import ParameterSelection
42-
from processing.core.outputs import OutputVector
4340

4441

4542
class ExecuteSQL(QgisAlgorithm):
@@ -54,7 +51,7 @@ class ExecuteSQL(QgisAlgorithm):
5451
INPUT_GEOMETRY_FIELD = 'INPUT_GEOMETRY_FIELD'
5552
INPUT_GEOMETRY_TYPE = 'INPUT_GEOMETRY_TYPE'
5653
INPUT_GEOMETRY_CRS = 'INPUT_GEOMETRY_CRS'
57-
OUTPUT_LAYER = 'OUTPUT_LAYER'
54+
OUTPUT = 'OUTPUT'
5855

5956
def group(self):
6057
return self.tr('Vector general tools')
@@ -63,19 +60,19 @@ def __init__(self):
6360
super().__init__()
6461

6562
def initAlgorithm(self, config=None):
66-
self.addParameter(ParameterMultipleInput(name=self.INPUT_DATASOURCES,
67-
description=self.tr('Additional input datasources (called input1, .., inputN in the query)'),
68-
optional=True))
63+
self.addParameter(QgsProcessingParameterMultipleLayers(name=self.INPUT_DATASOURCES,
64+
description=self.tr('Additional input datasources (called input1, .., inputN in the query)'),
65+
optional=True))
6966

70-
self.addParameter(ParameterString(name=self.INPUT_QUERY,
71-
description=self.tr('SQL query'),
72-
multiline=True))
67+
self.addParameter(QgsProcessingParameterString(name=self.INPUT_QUERY,
68+
description=self.tr('SQL query'),
69+
multiLine=True))
7370

74-
self.addParameter(ParameterString(name=self.INPUT_UID_FIELD,
75-
description=self.tr('Unique identifier field'), optional=True))
71+
self.addParameter(QgsProcessingParameterString(name=self.INPUT_UID_FIELD,
72+
description=self.tr('Unique identifier field'), optional=True))
7673

77-
self.addParameter(ParameterString(name=self.INPUT_GEOMETRY_FIELD,
78-
description=self.tr('Geometry field'), optional=True))
74+
self.addParameter(QgsProcessingParameterString(name=self.INPUT_GEOMETRY_FIELD,
75+
description=self.tr('Geometry field'), optional=True))
7976

8077
self.geometryTypes = [
8178
self.tr('Autodetect'),
@@ -86,13 +83,13 @@ def initAlgorithm(self, config=None):
8683
'MultiPoint',
8784
'MultiLineString',
8885
'MultiPolygon']
89-
self.addParameter(ParameterSelection(self.INPUT_GEOMETRY_TYPE,
90-
self.tr('Geometry type'), self.geometryTypes, optional=True))
86+
self.addParameter(QgsProcessingParameterEnum(self.INPUT_GEOMETRY_TYPE,
87+
self.tr('Geometry type'), options=self.geometryTypes, optional=True))
9188

92-
self.addParameter(ParameterCrs(self.INPUT_GEOMETRY_CRS,
93-
self.tr('CRS'), optional=True))
89+
self.addParameter(QgsProcessingParameterCrs(self.INPUT_GEOMETRY_CRS,
90+
self.tr('CRS'), optional=True))
9491

95-
self.addOutput(OutputVector(self.OUTPUT_LAYER, self.tr('SQL Output')))
92+
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('SQL Output')))
9693

9794
def name(self):
9895
return 'executesql'
@@ -101,24 +98,19 @@ def displayName(self):
10198
return self.tr('Execute SQL')
10299

103100
def processAlgorithm(self, parameters, context, feedback):
104-
layers = self.getParameterValue(self.INPUT_DATASOURCES)
105-
query = self.getParameterValue(self.INPUT_QUERY)
106-
uid_field = self.getParameterValue(self.INPUT_UID_FIELD)
107-
geometry_field = self.getParameterValue(self.INPUT_GEOMETRY_FIELD)
108-
geometry_type = self.getParameterValue(self.INPUT_GEOMETRY_TYPE)
109-
geometry_crs = self.getParameterValue(self.INPUT_GEOMETRY_CRS)
101+
layers = self.parameterAsLayerList(parameters, self.INPUT_DATASOURCES, context)
102+
query = self.parameterAsString(parameters, self.INPUT_QUERY, context)
103+
uid_field = self.parameterAsString(parameters, self.INPUT_UID_FIELD, context)
104+
geometry_field = self.parameterAsString(parameters, self.INPUT_GEOMETRY_FIELD, context)
105+
geometry_type = self.parameterAsEnum(parameters, self.INPUT_GEOMETRY_TYPE, context)
106+
geometry_crs = self.parameterAsCrs(parameters, self.INPUT_GEOMETRY_CRS, context)
110107

111108
df = QgsVirtualLayerDefinition()
112-
layerIdx = 1
113-
if layers:
114-
for layerSource in layers.split(';'):
115-
layer = QgsProcessingUtils.mapLayerFromString(layerSource, context)
116-
if layer:
117-
df.addSource('input{}'.format(layerIdx), layer.id())
118-
layerIdx += 1
109+
for layerIdx, layer in enumerate(layers):
110+
df.addSource('input{}'.format(layerIdx + 1), layer.id())
119111

120112
if query == '':
121-
raise GeoAlgorithmExecutionException(
113+
raise QgsProcessingException(
122114
self.tr('Empty SQL. Please enter valid SQL expression and try again.'))
123115
else:
124116
df.setQuery(query)
@@ -133,26 +125,22 @@ def processAlgorithm(self, parameters, context, feedback):
133125
df.setGeometryField(geometry_field)
134126
if geometry_type > 1:
135127
df.setGeometryWkbType(geometry_type - 1)
136-
if geometry_crs:
137-
crs = QgsCoordinateReferenceSystem(geometry_crs)
138-
if crs.isValid():
139-
df.setGeometrySrid(crs.postgisSrid())
128+
if geometry_crs.isValid():
129+
df.setGeometrySrid(geometry_crs.postgisSrid())
140130

141131
vLayer = QgsVectorLayer(df.toString(), "temp_vlayer", "virtual")
142132
if not vLayer.isValid():
143-
raise GeoAlgorithmExecutionException(vLayer.dataProvider().error().message())
133+
raise QgsProcessingException(vLayer.dataProvider().error().message())
144134

145-
writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter(vLayer.fields(),
146-
vLayer.wkbType() if geometry_type != 1 else 1,
147-
vLayer.crs(), context)
135+
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
136+
vLayer.fields(), vLayer.wkbType() if geometry_type != 1 else 1, vLayer.crs())
148137

149-
features = QgsProcessingUtils.getFeatures(vLayer, context)
138+
features = vLayer.getFeatures()
150139
total = 100.0 / vLayer.featureCount() if vLayer.featureCount() else 0
151-
outFeat = QgsFeature()
152140
for current, inFeat in enumerate(features):
153-
outFeat.setAttributes(inFeat.attributes())
154-
if geometry_type != 1:
155-
outFeat.setGeometry(inFeat.geometry())
156-
writer.addFeature(outFeat, QgsFeatureSink.FastInsert)
141+
if feedback.isCanceled():
142+
break
143+
144+
sink.addFeature(inFeat, QgsFeatureSink.FastInsert)
157145
feedback.setProgress(int(current * total))
158-
del writer
146+
return {self.OUTPUT: dest_id}

‎python/plugins/processing/algs/qgis/FieldPyculator.py

Lines changed: 50 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -29,30 +29,27 @@
2929
import sys
3030

3131
from qgis.PyQt.QtCore import QVariant
32-
from qgis.core import (QgsFeature,
32+
from qgis.core import (QgsProcessingException,
3333
QgsField,
3434
QgsFeatureSink,
35-
QgsApplication,
36-
QgsProcessingUtils)
35+
QgsProcessingParameterFeatureSource,
36+
QgsProcessingParameterString,
37+
QgsProcessingParameterEnum,
38+
QgsProcessingParameterNumber,
39+
QgsProcessingParameterFeatureSink)
3740
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
38-
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
39-
from processing.core.parameters import ParameterVector
40-
from processing.core.parameters import ParameterString
41-
from processing.core.parameters import ParameterNumber
42-
from processing.core.parameters import ParameterSelection
43-
from processing.core.outputs import OutputVector
4441

4542

4643
class FieldsPyculator(QgisAlgorithm):
4744

48-
INPUT_LAYER = 'INPUT_LAYER'
45+
INPUT = 'INPUT'
4946
FIELD_NAME = 'FIELD_NAME'
5047
FIELD_TYPE = 'FIELD_TYPE'
5148
FIELD_LENGTH = 'FIELD_LENGTH'
5249
FIELD_PRECISION = 'FIELD_PRECISION'
5350
GLOBAL = 'GLOBAL'
5451
FORMULA = 'FORMULA'
55-
OUTPUT_LAYER = 'OUTPUT_LAYER'
52+
OUTPUT = 'OUTPUT'
5653
RESULT_VAR_NAME = 'value'
5754

5855
TYPES = [QVariant.Int, QVariant.Double, QVariant.String]
@@ -68,21 +65,21 @@ def initAlgorithm(self, config=None):
6865
self.tr('Float'),
6966
self.tr('String')]
7067

71-
self.addParameter(ParameterVector(self.INPUT_LAYER,
72-
self.tr('Input layer')))
73-
self.addParameter(ParameterString(self.FIELD_NAME,
74-
self.tr('Result field name'), 'NewField'))
75-
self.addParameter(ParameterSelection(self.FIELD_TYPE,
76-
self.tr('Field type'), self.type_names))
77-
self.addParameter(ParameterNumber(self.FIELD_LENGTH,
78-
self.tr('Field length'), 1, 255, 10))
79-
self.addParameter(ParameterNumber(self.FIELD_PRECISION,
80-
self.tr('Field precision'), 0, 10, 0))
81-
self.addParameter(ParameterString(self.GLOBAL,
82-
self.tr('Global expression'), multiline=True, optional=True))
83-
self.addParameter(ParameterString(self.FORMULA,
84-
self.tr('Formula'), 'value = ', multiline=True))
85-
self.addOutput(OutputVector(self.OUTPUT_LAYER, self.tr('Calculated')))
68+
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT, self.tr('Input layer')))
69+
self.addParameter(QgsProcessingParameterString(self.FIELD_NAME,
70+
self.tr('Result field name'), defaultValue='NewField'))
71+
self.addParameter(QgsProcessingParameterEnum(self.FIELD_TYPE,
72+
self.tr('Field type'), options=self.type_names))
73+
self.addParameter(QgsProcessingParameterNumber(self.FIELD_LENGTH,
74+
self.tr('Field length'), minValue=1, maxValue=255, defaultValue=10))
75+
self.addParameter(QgsProcessingParameterNumber(self.FIELD_PRECISION,
76+
self.tr('Field precision'), minValue=0, maxValue=15, defaultValue=3))
77+
self.addParameter(QgsProcessingParameterString(self.GLOBAL,
78+
self.tr('Global expression'), multiLine=True, optional=True))
79+
self.addParameter(QgsProcessingParameterString(self.FORMULA,
80+
self.tr('Formula'), defaultValue='value = ', multiLine=True))
81+
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT,
82+
self.tr('Calculated')))
8683

8784
def name(self):
8885
return 'advancedpythonfieldcalculator'
@@ -91,33 +88,33 @@ def displayName(self):
9188
return self.tr('Advanced Python field calculator')
9289

9390
def processAlgorithm(self, parameters, context, feedback):
94-
fieldName = self.getParameterValue(self.FIELD_NAME)
95-
fieldType = self.getParameterValue(self.FIELD_TYPE)
96-
fieldLength = self.getParameterValue(self.FIELD_LENGTH)
97-
fieldPrecision = self.getParameterValue(self.FIELD_PRECISION)
98-
code = self.getParameterValue(self.FORMULA)
99-
globalExpression = self.getParameterValue(self.GLOBAL)
100-
output = self.getOutputFromName(self.OUTPUT_LAYER)
101-
102-
layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context)
103-
fields = layer.fields()
104-
fields.append(QgsField(fieldName, self.TYPES[fieldType], '',
105-
fieldLength, fieldPrecision))
106-
writer = output.getVectorWriter(fields, layer.wkbType(), layer.crs(), context)
107-
outFeat = QgsFeature()
91+
source = self.parameterAsSource(parameters, self.INPUT, context)
92+
field_name = self.parameterAsString(parameters, self.FIELD_NAME, context)
93+
field_type = self.TYPES[self.parameterAsEnum(parameters, self.FIELD_TYPE, context)]
94+
width = self.parameterAsInt(parameters, self.FIELD_LENGTH, context)
95+
precision = self.parameterAsInt(parameters, self.FIELD_PRECISION, context)
96+
code = self.parameterAsString(parameters, self.FORMULA, context)
97+
globalExpression = self.parameterAsString(parameters, self.GLOBAL, context)
98+
99+
fields = source.fields()
100+
fields.append(QgsField(field_name, self.TYPES[field_type], '',
101+
width, precision))
108102
new_ns = {}
109103

104+
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
105+
fields, source.wkbType(), source.sourceCrs())
106+
110107
# Run global code
111108
if globalExpression.strip() != '':
112109
try:
113110
bytecode = compile(globalExpression, '<string>', 'exec')
114111
exec(bytecode, new_ns)
115112
except:
116-
raise GeoAlgorithmExecutionException(
113+
raise QgsProcessingException(
117114
self.tr("FieldPyculator code execute error.Global code block can't be executed!\n{0}\n{1}").format(str(sys.exc_info()[0].__name__), str(sys.exc_info()[1])))
118115

119116
# Replace all fields tags
120-
fields = layer.fields()
117+
fields = source.fields()
121118
num = 0
122119
for field in fields:
123120
field_name = str(field.name())
@@ -136,13 +133,17 @@ def processAlgorithm(self, parameters, context, feedback):
136133
try:
137134
bytecode = compile(code, '<string>', 'exec')
138135
except:
139-
raise GeoAlgorithmExecutionException(
136+
raise QgsProcessingException(
140137
self.tr("FieldPyculator code execute error. Field code block can't be executed!\n{0}\n{1}").format(str(sys.exc_info()[0].__name__), str(sys.exc_info()[1])))
141138

142139
# Run
143-
features = QgsProcessingUtils.getFeatures(layer, context)
144-
total = 100.0 / layer.featureCount() if layer.featureCount() else 0
140+
features = source.getFeatures()
141+
total = 100.0 / source.featureCount() if source.featureCount() else 0
142+
145143
for current, feat in enumerate(features):
144+
if feedback.isCanceled():
145+
break
146+
146147
feedback.setProgress(int(current * total))
147148
attrs = feat.attributes()
148149
feat_id = feat.id()
@@ -168,18 +169,17 @@ def processAlgorithm(self, parameters, context, feedback):
168169

169170
# Check result
170171
if self.RESULT_VAR_NAME not in new_ns:
171-
raise GeoAlgorithmExecutionException(
172+
raise QgsProcessingException(
172173
self.tr("FieldPyculator code execute error\n"
173174
"Field code block does not return '{0}' variable! "
174175
"Please declare this variable in your code!").format(self.RESULT_VAR_NAME))
175176

176177
# Write feature
177-
outFeat.setGeometry(feat.geometry())
178178
attrs.append(new_ns[self.RESULT_VAR_NAME])
179-
outFeat.setAttributes(attrs)
180-
writer.addFeature(outFeat, QgsFeatureSink.FastInsert)
179+
feat.setAttributes(attrs)
180+
sink.addFeature(feat, QgsFeatureSink.FastInsert)
181181

182-
del writer
182+
return {self.OUTPUT: dest_id}
183183

184184
def checkParameterValues(self, parameters, context):
185185
# TODO check that formula is correct and fields exist

0 commit comments

Comments
 (0)
Please sign in to comment.