Skip to content
Permalink
Browse files

Upgrade ported python algs to be thread ready

  • Loading branch information
nyalldawson committed Jul 6, 2017
1 parent c2621b1 commit cd7776ca1c105354ecba146c2366607e5912a48d
Showing with 924 additions and 588 deletions.
  1. +28 −15 python/plugins/processing/algs/qgis/AddTableField.py
  2. +21 −13 python/plugins/processing/algs/qgis/Aspect.py
  3. +17 −9 python/plugins/processing/algs/qgis/AutoincrementalField.py
  4. +29 −19 python/plugins/processing/algs/qgis/BasicStatistics.py
  5. +18 −9 python/plugins/processing/algs/qgis/Boundary.py
  6. +16 −8 python/plugins/processing/algs/qgis/BoundingBox.py
  7. +59 −43 python/plugins/processing/algs/qgis/CheckValidity.py
  8. +17 −9 python/plugins/processing/algs/qgis/CreateAttributeIndex.py
  9. +26 −16 python/plugins/processing/algs/qgis/DeleteColumn.py
  10. +21 −12 python/plugins/processing/algs/qgis/DeleteHoles.py
  11. +19 −10 python/plugins/processing/algs/qgis/DensifyGeometries.py
  12. +19 −10 python/plugins/processing/algs/qgis/DensifyGeometriesInterval.py
  13. +22 −13 python/plugins/processing/algs/qgis/DropGeometry.py
  14. +18 −9 python/plugins/processing/algs/qgis/ExtentFromLayer.py
  15. +17 −9 python/plugins/processing/algs/qgis/FixGeometry.py
  16. +41 −26 python/plugins/processing/algs/qgis/GridPolygon.py
  17. +63 −51 python/plugins/processing/algs/qgis/ImportIntoPostGIS.py
  18. +61 −45 python/plugins/processing/algs/qgis/ImportIntoSpatialite.py
  19. +38 −26 python/plugins/processing/algs/qgis/Merge.py
  20. +13 −5 python/plugins/processing/algs/qgis/PostGISExecuteSQL.py
  21. +30 −21 python/plugins/processing/algs/qgis/RandomExtract.py
  22. +31 −19 python/plugins/processing/algs/qgis/RandomExtractWithinSubsets.py
  23. +38 −24 python/plugins/processing/algs/qgis/RegularPoints.py
  24. +16 −10 python/plugins/processing/algs/qgis/SaveSelectedFeatures.py
  25. +34 −21 python/plugins/processing/algs/qgis/SelectByAttribute.py
  26. +22 −10 python/plugins/processing/algs/qgis/SelectByExpression.py
  27. +26 −15 python/plugins/processing/algs/qgis/SimplifyGeometries.py
  28. +23 −12 python/plugins/processing/algs/qgis/Smooth.py
  29. +13 −5 python/plugins/processing/algs/qgis/SpatialiteExecuteSQL.py
  30. +28 −19 python/plugins/processing/algs/qgis/SymmetricalDifference.py
  31. +31 −25 python/plugins/processing/algs/qgis/VectorSplit.py
  32. +25 −15 python/plugins/processing/algs/qgis/ZonalStatistics.py
  33. +25 −16 python/plugins/processing/script/ScriptAlgorithm.py
  34. +11 −11 python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml
  35. +1 −1 src/core/processing/qgsnativealgorithms.cpp
  36. +7 −7 tests/src/core/testqgsprocessing.cpp
@@ -74,28 +74,38 @@ def __init__(self):
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT_LAYER, self.tr('Added')))
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT_LAYER, self.tr('Added')))

self.source = None
self.fieldType = None
self.fieldLength = None
self.fieldName = None
self.fieldPrecision = None
self.sink = None
self.dest_id = None

def name(self):
return 'addfieldtoattributestable'

def displayName(self):
return self.tr('Add field to attributes table')

def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT_LAYER, context)
def prepareAlgorithm(self, parameters, context, feedback):
self.source = self.parameterAsSource(parameters, self.INPUT_LAYER, context)

fieldType = self.parameterAsEnum(parameters, self.FIELD_TYPE, context)
fieldName = self.parameterAsString(parameters, self.FIELD_NAME, context)
fieldLength = self.parameterAsInt(parameters, self.FIELD_LENGTH, context)
fieldPrecision = self.parameterAsInt(parameters, self.FIELD_PRECISION, context)
self.fieldType = self.parameterAsEnum(parameters, self.FIELD_TYPE, context)
self.fieldName = self.parameterAsString(parameters, self.FIELD_NAME, context)
self.fieldLength = self.parameterAsInt(parameters, self.FIELD_LENGTH, context)
self.fieldPrecision = self.parameterAsInt(parameters, self.FIELD_PRECISION, context)

fields = source.fields()
fields.append(QgsField(fieldName, self.TYPES[fieldType], '',
fieldLength, fieldPrecision))
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT_LAYER, context,
fields, source.wkbType(), source.sourceCrs())
fields = self.source.fields()
fields.append(QgsField(self.fieldName, self.TYPES[self.fieldType], '',
self.fieldLength, self.fieldPrecision))
(self.sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT_LAYER, context,
fields, self.source.wkbType(), self.source.sourceCrs())
return True

features = source.getFeatures()
total = 100.0 / source.featureCount() if source.featureCount() else 0
def processAlgorithm(self, context, feedback):
features = self.source.getFeatures()
total = 100.0 / self.source.featureCount() if self.source.featureCount() else 0

for current, input_feature in enumerate(features):
if feedback.isCanceled():
@@ -106,7 +116,10 @@ def processAlgorithm(self, parameters, context, feedback):
attributes.append(None)
output_feature.setAttributes(attributes)

sink.addFeature(output_feature, QgsFeatureSink.FastInsert)
self.sink.addFeature(output_feature, QgsFeatureSink.FastInsert)
feedback.setProgress(int(current * total))

return {self.OUTPUT_LAYER: dest_id}
return True

def postProcessAlgorithm(self, context, feedback):
return {self.OUTPUT_LAYER: self.dest_id}
@@ -47,7 +47,7 @@

class Aspect(QgisAlgorithm):

INPUT_LAYER = 'INPUT_LAYER'
INPUT = 'INPUT'
Z_FACTOR = 'Z_FACTOR'
OUTPUT_LAYER = 'OUTPUT_LAYER'

@@ -60,30 +60,38 @@ def group(self):
def __init__(self):
super().__init__()

self.addParameter(QgsProcessingParameterRasterLayer(self.INPUT_LAYER,
self.addParameter(QgsProcessingParameterRasterLayer(self.INPUT,
self.tr('Elevation layer')))
self.addParameter(QgsProcessingParameterNumber(self.Z_FACTOR,
self.tr('Z factor'), QgsProcessingParameterNumber.Double,
1, False, 1, 999999.99))
self.addParameter(QgsProcessingParameterRasterOutput(self.OUTPUT_LAYER, self.tr('Aspect')))
self.addOutput(QgsProcessingOutputRasterLayer(self.OUTPUT_LAYER, self.tr('Aspect')))
self.addParameter(QgsProcessingParameterRasterOutput(self.OUTPUT, self.tr('Aspect')))
self.addOutput(QgsProcessingOutputRasterLayer(self.OUTPUT, self.tr('Aspect')))

self.inputFile = None
self.outputFile = None
self.outputFormat = None
self.zFactor = None

def name(self):
return 'aspect'

def displayName(self):
return self.tr('Aspect')

def processAlgorithm(self, parameters, context, feedback):
inputFile = exportRasterLayer(self.parameterAsRasterLayer(parameters, self.INPUT_LAYER, context))
zFactor = self.parameterAsDouble(parameters, self.Z_FACTOR, context)
def prepareAlgorithm(self, parameters, context, feedback):
self.inputFile = exportRasterLayer(self.parameterAsRasterLayer(parameters, self.INPUT, context))
self.zFactor = self.parameterAsDouble(parameters, self.Z_FACTOR, context)

outputFile = self.parameterAsRasterOutputLayer(parameters, self.OUTPUT_LAYER, context)
self.outputFile = self.parameterAsRasterOutputLayer(parameters, self.OUTPUT, context)

outputFormat = raster.formatShortNameFromFileName(outputFile)
self.outputFormat = raster.formatShortNameFromFileName(self.outputFile)
return True

aspect = QgsAspectFilter(inputFile, outputFile, outputFormat)
aspect.setZFactor(zFactor)
aspect.processRaster(feedback)
def processAlgorithm(self, context, feedback):
aspect = QgsAspectFilter(self.inputFile, self.outputFile, self.outputFormat)
aspect.setZFactor(self.zFactor)
return aspect.processRaster(feedback) == 0

return {self.OUTPUT_LAYER: outputFile}
def postProcessAlgorithm(self, context, feedback):
return {self.OUTPUT: self.outputFile}
@@ -51,6 +51,10 @@ def __init__(self):
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Incremented')))
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Incremented')))

self.source = None
self.sink = None
self.dest_id = None

def group(self):
return self.tr('Vector table tools')

@@ -60,16 +64,18 @@ def name(self):
def displayName(self):
return self.tr('Add autoincremental field')

def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
fields = source.fields()
def prepareAlgorithm(self, parameters, context, feedback):
self.source = self.parameterAsSource(parameters, self.INPUT, context)
fields = self.source.fields()
fields.append(QgsField('AUTO', QVariant.Int))

(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
fields, source.wkbType(), source.sourceCrs())
(self.sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
fields, self.source.wkbType(), self.source.sourceCrs())
return True

features = source.getFeatures()
total = 100.0 / source.featureCount() if source.featureCount() else 0
def processAlgorithm(self, context, feedback):
features = self.source.getFeatures()
total = 100.0 / self.source.featureCount() if self.source.featureCount() else 0
for current, input_feature in enumerate(features):
if feedback.isCanceled():
break
@@ -79,7 +85,9 @@ def processAlgorithm(self, parameters, context, feedback):
attributes.append(current)
output_feature.setAttributes(attributes)

sink.addFeature(output_feature, QgsFeatureSink.FastInsert)
self.sink.addFeature(output_feature, QgsFeatureSink.FastInsert)
feedback.setProgress(int(current * total))
return True

return {self.OUTPUT: dest_id}
def postProcessAlgorithm(self, context, feedback):
return {self.OUTPUT: self.dest_id}
@@ -119,42 +119,52 @@ def __init__(self):
self.addOutput(QgsProcessingOutputNumber(self.THIRDQUARTILE, self.tr('Third quartile')))
self.addOutput(QgsProcessingOutputNumber(self.IQR, self.tr('Interquartile Range (IQR)')))

self.source = None
self.field = None
self.field_name = None
self.output_file = None
self.results = {}

def name(self):
return 'basicstatisticsforfields'

def displayName(self):
return self.tr('Basic statistics for fields')

def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT_LAYER, context)
field_name = self.parameterAsString(parameters, self.FIELD_NAME, context)
field = source.fields().at(source.fields().lookupField(field_name))
def prepareAlgorithm(self, parameters, context, feedback):
self.source = self.parameterAsSource(parameters, self.INPUT_LAYER, context)
self.field_name = self.parameterAsString(parameters, self.FIELD_NAME, context)
self.field = self.source.fields().at(self.source.fields().lookupField(self.field_name))

output_file = self.parameterAsFileOutput(parameters, self.OUTPUT_HTML_FILE, context)
self.output_file = self.parameterAsFileOutput(parameters, self.OUTPUT_HTML_FILE, context)
return True

request = QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry).setSubsetOfAttributes([field_name], source.fields())
features = source.getFeatures(request)
count = source.featureCount()
def processAlgorithm(self, context, feedback):
request = QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry).setSubsetOfAttributes([self.field_name], self.source.fields())
features = self.source.getFeatures(request)
count = self.source.featureCount()

data = []
data.append(self.tr('Analyzed field: {}').format(field_name))
results = {}
data.append(self.tr('Analyzed field: {}').format(self.field_name))

if field.isNumeric():
d, results = self.calcNumericStats(features, feedback, field, count)
if self.field.isNumeric():
d, self.results = self.calcNumericStats(features, feedback, self.field, count)
data.extend(d)
elif field.type() in (QVariant.Date, QVariant.Time, QVariant.DateTime):
d, results = self.calcDateTimeStats(features, feedback, field, count)
elif self.field.type() in (QVariant.Date, QVariant.Time, QVariant.DateTime):
d, self.results = self.calcDateTimeStats(features, feedback, self.field, count)
data.extend(d)
else:
d, results = self.calcStringStats(features, feedback, field, count)
d, self.results = self.calcStringStats(features, feedback, self.field, count)
data.extend(d)

if output_file:
self.createHTML(output_file, data)
results[self.OUTPUT_HTML_FILE] = output_file
if self.output_file:
self.createHTML(self.output_file, data)
self.results[self.OUTPUT_HTML_FILE] = self.output_file

return True

return results
def postProcessAlgorithm(self, context, feedback):
return self.results

def calcNumericStats(self, features, feedback, field, count):
total = 100.0 / count if count else 0
@@ -58,6 +58,10 @@ def __init__(self):
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT_LAYER, self.tr('Boundary')))
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT_LAYER, self.tr("Boundaries")))

self.source = None
self.sink = None
self.dest_id = None

def icon(self):
return QIcon(os.path.join(pluginPath, 'images', 'ftools', 'convex_hull.png'))

@@ -70,10 +74,11 @@ def name(self):
def displayName(self):
return self.tr('Boundary')

def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT_LAYER, context)
def prepareAlgorithm(self, parameters, context, feedback):
self.source = self.parameterAsSource(parameters, self.INPUT_LAYER, context)

input_wkb = source.wkbType()
input_wkb = self.source.wkbType()
output_wkb = None
if QgsWkbTypes.geometryType(input_wkb) == QgsWkbTypes.LineGeometry:
output_wkb = QgsWkbTypes.MultiPoint
elif QgsWkbTypes.geometryType(input_wkb) == QgsWkbTypes.PolygonGeometry:
@@ -83,11 +88,13 @@ def processAlgorithm(self, parameters, context, feedback):
if QgsWkbTypes.hasM(input_wkb):
output_wkb = QgsWkbTypes.addM(output_wkb)

(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT_LAYER, context,
source.fields(), output_wkb, source.sourceCrs())
(self.sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT_LAYER, context,
self.source.fields(), output_wkb, self.source.sourceCrs())
return True

features = source.getFeatures()
total = 100.0 / source.featureCount() if source.featureCount() else 0
def processAlgorithm(self, context, feedback):
features = self.source.getFeatures()
total = 100.0 / self.source.featureCount() if self.source.featureCount() else 0

for current, input_feature in enumerate(features):
if feedback.isCanceled():
@@ -102,7 +109,9 @@ def processAlgorithm(self, parameters, context, feedback):

output_feature.setGeometry(output_geometry)

sink.addFeature(output_feature, QgsFeatureSink.FastInsert)
self.sink.addFeature(output_feature, QgsFeatureSink.FastInsert)
feedback.setProgress(int(current * total))
return True

return {self.OUTPUT_LAYER: dest_id}
def postProcessAlgorithm(self, context, feedback):
return {self.OUTPUT_LAYER: self.dest_id}
@@ -66,20 +66,26 @@ def __init__(self):
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT_LAYER, self.tr('Bounds'), QgsProcessingParameterDefinition.TypeVectorPolygon))
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT_LAYER, self.tr("Bounds")))

self.source = None
self.sink = None
self.dest_id = None

def name(self):
return 'boundingboxes'

def displayName(self):
return self.tr('Bounding boxes')

def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT_LAYER, context)
def prepareAlgorithm(self, parameters, context, feedback):
self.source = self.parameterAsSource(parameters, self.INPUT_LAYER, context)

(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT_LAYER, context,
source.fields(), QgsWkbTypes.Polygon, source.sourceCrs())
(self.sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT_LAYER, context,
self.source.fields(), QgsWkbTypes.Polygon, self.source.sourceCrs())
return True

features = source.getFeatures()
total = 100.0 / source.featureCount() if source.featureCount() else 0
def processAlgorithm(self, context, feedback):
features = self.source.getFeatures()
total = 100.0 / self.source.featureCount() if self.source.featureCount() else 0

for current, input_feature in enumerate(features):
if feedback.isCanceled():
@@ -94,7 +100,9 @@ def processAlgorithm(self, parameters, context, feedback):

output_feature.setGeometry(output_geometry)

sink.addFeature(output_feature, QgsFeatureSink.FastInsert)
self.sink.addFeature(output_feature, QgsFeatureSink.FastInsert)
feedback.setProgress(int(current * total))
return True

return {self.OUTPUT_LAYER: dest_id}
def postProcessAlgorithm(self, context, feedback):
return {self.OUTPUT_LAYER: self.dest_id}

0 comments on commit cd7776c

Please sign in to comment.
You can’t perform that action at this time.