mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-16 00:03:12 -04:00
Upgrade ported python algs to be thread ready
This commit is contained in:
parent
c2621b1275
commit
cd7776ca1c
@ -74,28 +74,38 @@ class AddTableField(QgisAlgorithm):
|
|||||||
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT_LAYER, self.tr('Added')))
|
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT_LAYER, self.tr('Added')))
|
||||||
self.addOutput(QgsProcessingOutputVectorLayer(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):
|
def name(self):
|
||||||
return 'addfieldtoattributestable'
|
return 'addfieldtoattributestable'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Add field to attributes table')
|
return self.tr('Add field to attributes table')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
source = self.parameterAsSource(parameters, self.INPUT_LAYER, context)
|
self.source = self.parameterAsSource(parameters, self.INPUT_LAYER, context)
|
||||||
|
|
||||||
fieldType = self.parameterAsEnum(parameters, self.FIELD_TYPE, context)
|
self.fieldType = self.parameterAsEnum(parameters, self.FIELD_TYPE, context)
|
||||||
fieldName = self.parameterAsString(parameters, self.FIELD_NAME, context)
|
self.fieldName = self.parameterAsString(parameters, self.FIELD_NAME, context)
|
||||||
fieldLength = self.parameterAsInt(parameters, self.FIELD_LENGTH, context)
|
self.fieldLength = self.parameterAsInt(parameters, self.FIELD_LENGTH, context)
|
||||||
fieldPrecision = self.parameterAsInt(parameters, self.FIELD_PRECISION, context)
|
self.fieldPrecision = self.parameterAsInt(parameters, self.FIELD_PRECISION, context)
|
||||||
|
|
||||||
fields = source.fields()
|
fields = self.source.fields()
|
||||||
fields.append(QgsField(fieldName, self.TYPES[fieldType], '',
|
fields.append(QgsField(self.fieldName, self.TYPES[self.fieldType], '',
|
||||||
fieldLength, fieldPrecision))
|
self.fieldLength, self.fieldPrecision))
|
||||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT_LAYER, context,
|
(self.sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT_LAYER, context,
|
||||||
fields, source.wkbType(), source.sourceCrs())
|
fields, self.source.wkbType(), self.source.sourceCrs())
|
||||||
|
return True
|
||||||
|
|
||||||
features = source.getFeatures()
|
def processAlgorithm(self, context, feedback):
|
||||||
total = 100.0 / source.featureCount() if source.featureCount() else 0
|
features = self.source.getFeatures()
|
||||||
|
total = 100.0 / self.source.featureCount() if self.source.featureCount() else 0
|
||||||
|
|
||||||
for current, input_feature in enumerate(features):
|
for current, input_feature in enumerate(features):
|
||||||
if feedback.isCanceled():
|
if feedback.isCanceled():
|
||||||
@ -106,7 +116,10 @@ class AddTableField(QgisAlgorithm):
|
|||||||
attributes.append(None)
|
attributes.append(None)
|
||||||
output_feature.setAttributes(attributes)
|
output_feature.setAttributes(attributes)
|
||||||
|
|
||||||
sink.addFeature(output_feature, QgsFeatureSink.FastInsert)
|
self.sink.addFeature(output_feature, QgsFeatureSink.FastInsert)
|
||||||
feedback.setProgress(int(current * total))
|
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 @@ pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
|
|||||||
|
|
||||||
class Aspect(QgisAlgorithm):
|
class Aspect(QgisAlgorithm):
|
||||||
|
|
||||||
INPUT_LAYER = 'INPUT_LAYER'
|
INPUT = 'INPUT'
|
||||||
Z_FACTOR = 'Z_FACTOR'
|
Z_FACTOR = 'Z_FACTOR'
|
||||||
OUTPUT_LAYER = 'OUTPUT_LAYER'
|
OUTPUT_LAYER = 'OUTPUT_LAYER'
|
||||||
|
|
||||||
@ -60,13 +60,18 @@ class Aspect(QgisAlgorithm):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.addParameter(QgsProcessingParameterRasterLayer(self.INPUT_LAYER,
|
self.addParameter(QgsProcessingParameterRasterLayer(self.INPUT,
|
||||||
self.tr('Elevation layer')))
|
self.tr('Elevation layer')))
|
||||||
self.addParameter(QgsProcessingParameterNumber(self.Z_FACTOR,
|
self.addParameter(QgsProcessingParameterNumber(self.Z_FACTOR,
|
||||||
self.tr('Z factor'), QgsProcessingParameterNumber.Double,
|
self.tr('Z factor'), QgsProcessingParameterNumber.Double,
|
||||||
1, False, 1, 999999.99))
|
1, False, 1, 999999.99))
|
||||||
self.addParameter(QgsProcessingParameterRasterOutput(self.OUTPUT_LAYER, self.tr('Aspect')))
|
self.addParameter(QgsProcessingParameterRasterOutput(self.OUTPUT, self.tr('Aspect')))
|
||||||
self.addOutput(QgsProcessingOutputRasterLayer(self.OUTPUT_LAYER, 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):
|
def name(self):
|
||||||
return 'aspect'
|
return 'aspect'
|
||||||
@ -74,16 +79,19 @@ class Aspect(QgisAlgorithm):
|
|||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Aspect')
|
return self.tr('Aspect')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
inputFile = exportRasterLayer(self.parameterAsRasterLayer(parameters, self.INPUT_LAYER, context))
|
self.inputFile = exportRasterLayer(self.parameterAsRasterLayer(parameters, self.INPUT, context))
|
||||||
zFactor = self.parameterAsDouble(parameters, self.Z_FACTOR, 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)
|
def processAlgorithm(self, context, feedback):
|
||||||
aspect.setZFactor(zFactor)
|
aspect = QgsAspectFilter(self.inputFile, self.outputFile, self.outputFormat)
|
||||||
aspect.processRaster(feedback)
|
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 @@ class AutoincrementalField(QgisAlgorithm):
|
|||||||
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Incremented')))
|
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Incremented')))
|
||||||
self.addOutput(QgsProcessingOutputVectorLayer(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):
|
def group(self):
|
||||||
return self.tr('Vector table tools')
|
return self.tr('Vector table tools')
|
||||||
|
|
||||||
@ -60,16 +64,18 @@ class AutoincrementalField(QgisAlgorithm):
|
|||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Add autoincremental field')
|
return self.tr('Add autoincremental field')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
source = self.parameterAsSource(parameters, self.INPUT, context)
|
self.source = self.parameterAsSource(parameters, self.INPUT, context)
|
||||||
fields = source.fields()
|
fields = self.source.fields()
|
||||||
fields.append(QgsField('AUTO', QVariant.Int))
|
fields.append(QgsField('AUTO', QVariant.Int))
|
||||||
|
|
||||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
(self.sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
||||||
fields, source.wkbType(), source.sourceCrs())
|
fields, self.source.wkbType(), self.source.sourceCrs())
|
||||||
|
return True
|
||||||
|
|
||||||
features = source.getFeatures()
|
def processAlgorithm(self, context, feedback):
|
||||||
total = 100.0 / source.featureCount() if source.featureCount() else 0
|
features = self.source.getFeatures()
|
||||||
|
total = 100.0 / self.source.featureCount() if self.source.featureCount() else 0
|
||||||
for current, input_feature in enumerate(features):
|
for current, input_feature in enumerate(features):
|
||||||
if feedback.isCanceled():
|
if feedback.isCanceled():
|
||||||
break
|
break
|
||||||
@ -79,7 +85,9 @@ class AutoincrementalField(QgisAlgorithm):
|
|||||||
attributes.append(current)
|
attributes.append(current)
|
||||||
output_feature.setAttributes(attributes)
|
output_feature.setAttributes(attributes)
|
||||||
|
|
||||||
sink.addFeature(output_feature, QgsFeatureSink.FastInsert)
|
self.sink.addFeature(output_feature, QgsFeatureSink.FastInsert)
|
||||||
feedback.setProgress(int(current * total))
|
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 @@ class BasicStatisticsForField(QgisAlgorithm):
|
|||||||
self.addOutput(QgsProcessingOutputNumber(self.THIRDQUARTILE, self.tr('Third quartile')))
|
self.addOutput(QgsProcessingOutputNumber(self.THIRDQUARTILE, self.tr('Third quartile')))
|
||||||
self.addOutput(QgsProcessingOutputNumber(self.IQR, self.tr('Interquartile Range (IQR)')))
|
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):
|
def name(self):
|
||||||
return 'basicstatisticsforfields'
|
return 'basicstatisticsforfields'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Basic statistics for fields')
|
return self.tr('Basic statistics for fields')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
source = self.parameterAsSource(parameters, self.INPUT_LAYER, context)
|
self.source = self.parameterAsSource(parameters, self.INPUT_LAYER, context)
|
||||||
field_name = self.parameterAsString(parameters, self.FIELD_NAME, context)
|
self.field_name = self.parameterAsString(parameters, self.FIELD_NAME, context)
|
||||||
field = source.fields().at(source.fields().lookupField(field_name))
|
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())
|
def processAlgorithm(self, context, feedback):
|
||||||
features = source.getFeatures(request)
|
request = QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry).setSubsetOfAttributes([self.field_name], self.source.fields())
|
||||||
count = source.featureCount()
|
features = self.source.getFeatures(request)
|
||||||
|
count = self.source.featureCount()
|
||||||
|
|
||||||
data = []
|
data = []
|
||||||
data.append(self.tr('Analyzed field: {}').format(field_name))
|
data.append(self.tr('Analyzed field: {}').format(self.field_name))
|
||||||
results = {}
|
|
||||||
|
|
||||||
if field.isNumeric():
|
if self.field.isNumeric():
|
||||||
d, results = self.calcNumericStats(features, feedback, field, count)
|
d, self.results = self.calcNumericStats(features, feedback, self.field, count)
|
||||||
data.extend(d)
|
data.extend(d)
|
||||||
elif field.type() in (QVariant.Date, QVariant.Time, QVariant.DateTime):
|
elif self.field.type() in (QVariant.Date, QVariant.Time, QVariant.DateTime):
|
||||||
d, results = self.calcDateTimeStats(features, feedback, field, count)
|
d, self.results = self.calcDateTimeStats(features, feedback, self.field, count)
|
||||||
data.extend(d)
|
data.extend(d)
|
||||||
else:
|
else:
|
||||||
d, results = self.calcStringStats(features, feedback, field, count)
|
d, self.results = self.calcStringStats(features, feedback, self.field, count)
|
||||||
data.extend(d)
|
data.extend(d)
|
||||||
|
|
||||||
if output_file:
|
if self.output_file:
|
||||||
self.createHTML(output_file, data)
|
self.createHTML(self.output_file, data)
|
||||||
results[self.OUTPUT_HTML_FILE] = output_file
|
self.results[self.OUTPUT_HTML_FILE] = self.output_file
|
||||||
|
|
||||||
return results
|
return True
|
||||||
|
|
||||||
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
|
return self.results
|
||||||
|
|
||||||
def calcNumericStats(self, features, feedback, field, count):
|
def calcNumericStats(self, features, feedback, field, count):
|
||||||
total = 100.0 / count if count else 0
|
total = 100.0 / count if count else 0
|
||||||
|
@ -58,6 +58,10 @@ class Boundary(QgisAlgorithm):
|
|||||||
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT_LAYER, self.tr('Boundary')))
|
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT_LAYER, self.tr('Boundary')))
|
||||||
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT_LAYER, self.tr("Boundaries")))
|
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT_LAYER, self.tr("Boundaries")))
|
||||||
|
|
||||||
|
self.source = None
|
||||||
|
self.sink = None
|
||||||
|
self.dest_id = None
|
||||||
|
|
||||||
def icon(self):
|
def icon(self):
|
||||||
return QIcon(os.path.join(pluginPath, 'images', 'ftools', 'convex_hull.png'))
|
return QIcon(os.path.join(pluginPath, 'images', 'ftools', 'convex_hull.png'))
|
||||||
|
|
||||||
@ -70,10 +74,11 @@ class Boundary(QgisAlgorithm):
|
|||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Boundary')
|
return self.tr('Boundary')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
source = self.parameterAsSource(parameters, self.INPUT_LAYER, context)
|
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:
|
if QgsWkbTypes.geometryType(input_wkb) == QgsWkbTypes.LineGeometry:
|
||||||
output_wkb = QgsWkbTypes.MultiPoint
|
output_wkb = QgsWkbTypes.MultiPoint
|
||||||
elif QgsWkbTypes.geometryType(input_wkb) == QgsWkbTypes.PolygonGeometry:
|
elif QgsWkbTypes.geometryType(input_wkb) == QgsWkbTypes.PolygonGeometry:
|
||||||
@ -83,11 +88,13 @@ class Boundary(QgisAlgorithm):
|
|||||||
if QgsWkbTypes.hasM(input_wkb):
|
if QgsWkbTypes.hasM(input_wkb):
|
||||||
output_wkb = QgsWkbTypes.addM(output_wkb)
|
output_wkb = QgsWkbTypes.addM(output_wkb)
|
||||||
|
|
||||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT_LAYER, context,
|
(self.sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT_LAYER, context,
|
||||||
source.fields(), output_wkb, source.sourceCrs())
|
self.source.fields(), output_wkb, self.source.sourceCrs())
|
||||||
|
return True
|
||||||
|
|
||||||
features = source.getFeatures()
|
def processAlgorithm(self, context, feedback):
|
||||||
total = 100.0 / source.featureCount() if source.featureCount() else 0
|
features = self.source.getFeatures()
|
||||||
|
total = 100.0 / self.source.featureCount() if self.source.featureCount() else 0
|
||||||
|
|
||||||
for current, input_feature in enumerate(features):
|
for current, input_feature in enumerate(features):
|
||||||
if feedback.isCanceled():
|
if feedback.isCanceled():
|
||||||
@ -102,7 +109,9 @@ class Boundary(QgisAlgorithm):
|
|||||||
|
|
||||||
output_feature.setGeometry(output_geometry)
|
output_feature.setGeometry(output_geometry)
|
||||||
|
|
||||||
sink.addFeature(output_feature, QgsFeatureSink.FastInsert)
|
self.sink.addFeature(output_feature, QgsFeatureSink.FastInsert)
|
||||||
feedback.setProgress(int(current * total))
|
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 @@ class BoundingBox(QgisAlgorithm):
|
|||||||
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT_LAYER, self.tr('Bounds'), QgsProcessingParameterDefinition.TypeVectorPolygon))
|
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT_LAYER, self.tr('Bounds'), QgsProcessingParameterDefinition.TypeVectorPolygon))
|
||||||
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT_LAYER, self.tr("Bounds")))
|
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT_LAYER, self.tr("Bounds")))
|
||||||
|
|
||||||
|
self.source = None
|
||||||
|
self.sink = None
|
||||||
|
self.dest_id = None
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'boundingboxes'
|
return 'boundingboxes'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Bounding boxes')
|
return self.tr('Bounding boxes')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
source = self.parameterAsSource(parameters, self.INPUT_LAYER, context)
|
self.source = self.parameterAsSource(parameters, self.INPUT_LAYER, context)
|
||||||
|
|
||||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT_LAYER, context,
|
(self.sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT_LAYER, context,
|
||||||
source.fields(), QgsWkbTypes.Polygon, source.sourceCrs())
|
self.source.fields(), QgsWkbTypes.Polygon, self.source.sourceCrs())
|
||||||
|
return True
|
||||||
|
|
||||||
features = source.getFeatures()
|
def processAlgorithm(self, context, feedback):
|
||||||
total = 100.0 / source.featureCount() if source.featureCount() else 0
|
features = self.source.getFeatures()
|
||||||
|
total = 100.0 / self.source.featureCount() if self.source.featureCount() else 0
|
||||||
|
|
||||||
for current, input_feature in enumerate(features):
|
for current, input_feature in enumerate(features):
|
||||||
if feedback.isCanceled():
|
if feedback.isCanceled():
|
||||||
@ -94,7 +100,9 @@ class BoundingBox(QgisAlgorithm):
|
|||||||
|
|
||||||
output_feature.setGeometry(output_geometry)
|
output_feature.setGeometry(output_geometry)
|
||||||
|
|
||||||
sink.addFeature(output_feature, QgsFeatureSink.FastInsert)
|
self.sink.addFeature(output_feature, QgsFeatureSink.FastInsert)
|
||||||
feedback.setProgress(int(current * total))
|
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}
|
||||||
|
@ -93,46 +93,60 @@ class CheckValidity(QgisAlgorithm):
|
|||||||
self.addOutput(QgsProcessingOutputVectorLayer(self.ERROR_OUTPUT, self.tr('Error output')))
|
self.addOutput(QgsProcessingOutputVectorLayer(self.ERROR_OUTPUT, self.tr('Error output')))
|
||||||
self.addOutput(QgsProcessingOutputNumber(self.ERROR_COUNT, self.tr('Count of errors')))
|
self.addOutput(QgsProcessingOutputNumber(self.ERROR_COUNT, self.tr('Count of errors')))
|
||||||
|
|
||||||
|
self.method = None
|
||||||
|
self.source = None
|
||||||
|
self.valid_output_sink = None
|
||||||
|
self.valid_output_dest_id = None
|
||||||
|
self.valid_count = 0
|
||||||
|
self.invalid_output_sink = None
|
||||||
|
self.invalid_output_dest_id = None
|
||||||
|
self.invalid_count = 0
|
||||||
|
self.error_output_sink = None
|
||||||
|
self.error_output_dest_id = None
|
||||||
|
self.error_count = 0
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'checkvalidity'
|
return 'checkvalidity'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Check validity')
|
return self.tr('Check validity')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
method_param = self.parameterAsEnum(parameters, self.METHOD, context)
|
method_param = self.parameterAsEnum(parameters, self.METHOD, context)
|
||||||
if method_param == 0:
|
if method_param == 0:
|
||||||
settings = QgsSettings()
|
settings = QgsSettings()
|
||||||
method = int(settings.value(settings_method_key, 0)) - 1
|
self.method = int(settings.value(settings_method_key, 0)) - 1
|
||||||
if method < 0:
|
if self.method < 0:
|
||||||
method = 0
|
self.method = 0
|
||||||
else:
|
else:
|
||||||
method = method_param - 1
|
self.method = method_param - 1
|
||||||
|
|
||||||
results = self.doCheck(method, parameters, context, feedback)
|
self.source = self.parameterAsSource(parameters, self.INPUT_LAYER, context)
|
||||||
return results
|
|
||||||
|
|
||||||
def doCheck(self, method, parameters, context, feedback):
|
(self.valid_output_sink, self.valid_output_dest_id) = self.parameterAsSink(parameters, self.VALID_OUTPUT,
|
||||||
source = self.parameterAsSource(parameters, self.INPUT_LAYER, context)
|
context,
|
||||||
|
self.source.fields(),
|
||||||
|
self.source.wkbType(),
|
||||||
|
self.source.sourceCrs())
|
||||||
|
|
||||||
(valid_output_sink, valid_output_dest_id) = self.parameterAsSink(parameters, self.VALID_OUTPUT, context,
|
invalid_fields = self.source.fields()
|
||||||
source.fields(), source.wkbType(), source.sourceCrs())
|
|
||||||
valid_count = 0
|
|
||||||
|
|
||||||
invalid_fields = source.fields()
|
|
||||||
invalid_fields.append(QgsField('_errors', QVariant.String, 'string', 255))
|
invalid_fields.append(QgsField('_errors', QVariant.String, 'string', 255))
|
||||||
(invalid_output_sink, invalid_output_dest_id) = self.parameterAsSink(parameters, self.INVALID_OUTPUT, context,
|
(self.invalid_output_sink, self.invalid_output_dest_id) = self.parameterAsSink(parameters, self.INVALID_OUTPUT,
|
||||||
invalid_fields, source.wkbType(), source.sourceCrs())
|
context,
|
||||||
invalid_count = 0
|
invalid_fields,
|
||||||
|
self.source.wkbType(),
|
||||||
|
self.source.sourceCrs())
|
||||||
|
|
||||||
error_fields = QgsFields()
|
error_fields = QgsFields()
|
||||||
error_fields.append(QgsField('message', QVariant.String, 'string', 255))
|
error_fields.append(QgsField('message', QVariant.String, 'string', 255))
|
||||||
(error_output_sink, error_output_dest_id) = self.parameterAsSink(parameters, self.ERROR_OUTPUT, context,
|
(self.error_output_sink, self.error_output_dest_id) = self.parameterAsSink(parameters, self.ERROR_OUTPUT, context,
|
||||||
error_fields, QgsWkbTypes.Point, source.sourceCrs())
|
error_fields, QgsWkbTypes.Point,
|
||||||
error_count = 0
|
self.source.sourceCrs())
|
||||||
|
return True
|
||||||
|
|
||||||
features = source.getFeatures(QgsFeatureRequest(), QgsProcessingFeatureSource.FlagSkipGeometryValidityChecks)
|
def processAlgorithm(self, context, feedback):
|
||||||
total = 100.0 / source.featureCount() if source.featureCount() else 0
|
features = self.source.getFeatures(QgsFeatureRequest(), QgsProcessingFeatureSource.FlagSkipGeometryValidityChecks)
|
||||||
|
total = 100.0 / self.source.featureCount() if self.source.featureCount() else 0
|
||||||
for current, inFeat in enumerate(features):
|
for current, inFeat in enumerate(features):
|
||||||
if feedback.isCanceled():
|
if feedback.isCanceled():
|
||||||
break
|
break
|
||||||
@ -141,10 +155,10 @@ class CheckValidity(QgisAlgorithm):
|
|||||||
|
|
||||||
valid = True
|
valid = True
|
||||||
if not geom.isNull() and not geom.isEmpty():
|
if not geom.isNull() and not geom.isEmpty():
|
||||||
errors = list(geom.validateGeometry(method))
|
errors = list(geom.validateGeometry(self.method))
|
||||||
if errors:
|
if errors:
|
||||||
# QGIS method return a summary at the end
|
# QGIS method return a summary at the end
|
||||||
if method == 1:
|
if self.method == 1:
|
||||||
errors.pop()
|
errors.pop()
|
||||||
valid = False
|
valid = False
|
||||||
reasons = []
|
reasons = []
|
||||||
@ -153,9 +167,9 @@ class CheckValidity(QgisAlgorithm):
|
|||||||
error_geom = QgsGeometry.fromPoint(error.where())
|
error_geom = QgsGeometry.fromPoint(error.where())
|
||||||
errFeat.setGeometry(error_geom)
|
errFeat.setGeometry(error_geom)
|
||||||
errFeat.setAttributes([error.what()])
|
errFeat.setAttributes([error.what()])
|
||||||
if error_output_sink:
|
if self.error_output_sink:
|
||||||
error_output_sink.addFeature(errFeat, QgsFeatureSink.FastInsert)
|
self.error_output_sink.addFeature(errFeat, QgsFeatureSink.FastInsert)
|
||||||
error_count += 1
|
self.error_count += 1
|
||||||
|
|
||||||
reasons.append(error.what())
|
reasons.append(error.what())
|
||||||
|
|
||||||
@ -169,26 +183,28 @@ class CheckValidity(QgisAlgorithm):
|
|||||||
outFeat.setAttributes(attrs)
|
outFeat.setAttributes(attrs)
|
||||||
|
|
||||||
if valid:
|
if valid:
|
||||||
if valid_output_sink:
|
if self.valid_output_sink:
|
||||||
valid_output_sink.addFeature(outFeat, QgsFeatureSink.FastInsert)
|
self.valid_output_sink.addFeature(outFeat, QgsFeatureSink.FastInsert)
|
||||||
valid_count += 1
|
self.valid_count += 1
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if invalid_output_sink:
|
if self.invalid_output_sink:
|
||||||
invalid_output_sink.addFeature(outFeat, QgsFeatureSink.FastInsert)
|
self.invalid_output_sink.addFeature(outFeat, QgsFeatureSink.FastInsert)
|
||||||
invalid_count += 1
|
self.invalid_count += 1
|
||||||
|
|
||||||
feedback.setProgress(int(current * total))
|
feedback.setProgress(int(current * total))
|
||||||
|
return True
|
||||||
|
|
||||||
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
results = {
|
results = {
|
||||||
self.VALID_COUNT: valid_count,
|
self.VALID_COUNT: self.valid_count,
|
||||||
self.INVALID_COUNT: invalid_count,
|
self.INVALID_COUNT: self.invalid_count,
|
||||||
self.ERROR_COUNT: error_count
|
self.ERROR_COUNT: self.error_count
|
||||||
}
|
}
|
||||||
if valid_output_sink:
|
if self.valid_output_sink:
|
||||||
results[self.VALID_OUTPUT] = valid_output_dest_id
|
results[self.VALID_OUTPUT] = self.valid_output_dest_id
|
||||||
if invalid_output_sink:
|
if self.invalid_output_sink:
|
||||||
results[self.INVALID_OUTPUT] = invalid_output_dest_id
|
results[self.INVALID_OUTPUT] = self.invalid_output_dest_id
|
||||||
if error_output_sink:
|
if self.error_output_sink:
|
||||||
results[self.ERROR_OUTPUT] = error_output_dest_id
|
results[self.ERROR_OUTPUT] = self.error_output_dest_id
|
||||||
return results
|
return results
|
||||||
|
@ -53,27 +53,35 @@ class CreateAttributeIndex(QgisAlgorithm):
|
|||||||
self.tr('Attribute to index'), None, self.INPUT))
|
self.tr('Attribute to index'), None, self.INPUT))
|
||||||
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Indexed layer')))
|
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Indexed layer')))
|
||||||
|
|
||||||
|
self.layer = None
|
||||||
|
self.field = None
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'createattributeindex'
|
return 'createattributeindex'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Create attribute index')
|
return self.tr('Create attribute index')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
layer = self.parameterAsVectorLayer(parameters, self.INPUT, context)
|
self.layer = self.parameterAsVectorLayer(parameters, self.INPUT, context)
|
||||||
field = self.parameterAsString(parameters, self.FIELD, context)
|
self.field = self.parameterAsString(parameters, self.FIELD, context)
|
||||||
provider = layer.dataProvider()
|
return True
|
||||||
|
|
||||||
field_index = layer.fields().lookupField(field)
|
def processAlgorithm(self, context, feedback):
|
||||||
if field_index < 0 or layer.fields().fieldOrigin(field_index) != QgsFields.OriginProvider:
|
provider = self.layer.dataProvider()
|
||||||
feedback.pushInfo(self.tr('Can not create attribute index on "{}"').format(field))
|
|
||||||
|
field_index = self.layer.fields().lookupField(self.field)
|
||||||
|
if field_index < 0 or self.layer.fields().fieldOrigin(field_index) != QgsFields.OriginProvider:
|
||||||
|
feedback.pushInfo(self.tr('Can not create attribute index on "{}"').format(self.field))
|
||||||
else:
|
else:
|
||||||
provider_index = layer.fields().fieldOriginIndex(field_index)
|
provider_index = self.layer.fields().fieldOriginIndex(field_index)
|
||||||
if provider.capabilities() & QgsVectorDataProvider.CreateAttributeIndex:
|
if provider.capabilities() & QgsVectorDataProvider.CreateAttributeIndex:
|
||||||
if not provider.createAttributeIndex(provider_index):
|
if not provider.createAttributeIndex(provider_index):
|
||||||
feedback.pushInfo(self.tr('Could not create attribute index'))
|
feedback.pushInfo(self.tr('Could not create attribute index'))
|
||||||
else:
|
else:
|
||||||
feedback.pushInfo(self.tr("Layer's data provider does not support "
|
feedback.pushInfo(self.tr("Layer's data provider does not support "
|
||||||
"creating attribute indexes"))
|
"creating attribute indexes"))
|
||||||
|
return True
|
||||||
|
|
||||||
return {self.OUTPUT: layer.id()}
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
|
return {self.OUTPUT: self.layer.id()}
|
||||||
|
@ -58,46 +58,56 @@ class DeleteColumn(QgisAlgorithm):
|
|||||||
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Output layer')))
|
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Output layer')))
|
||||||
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr("Output layer")))
|
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr("Output layer")))
|
||||||
|
|
||||||
|
self.source = None
|
||||||
|
self.fields_to_delete = None
|
||||||
|
self.sink = None
|
||||||
|
self.dest_id = None
|
||||||
|
self.field_indices = []
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'deletecolumn'
|
return 'deletecolumn'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Drop field(s)')
|
return self.tr('Drop field(s)')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
source = self.parameterAsSource(parameters, self.INPUT, context)
|
self.source = self.parameterAsSource(parameters, self.INPUT, context)
|
||||||
fields_to_delete = self.parameterAsFields(parameters, self.COLUMNS, context)
|
self.fields_to_delete = self.parameterAsFields(parameters, self.COLUMNS, context)
|
||||||
|
|
||||||
fields = source.fields()
|
fields = self.source.fields()
|
||||||
field_indices = []
|
|
||||||
# loop through twice - first we need to build up a list of original attribute indices
|
# loop through twice - first we need to build up a list of original attribute indices
|
||||||
for f in fields_to_delete:
|
for f in self.fields_to_delete:
|
||||||
index = fields.lookupField(f)
|
index = fields.lookupField(f)
|
||||||
field_indices.append(index)
|
self.field_indices.append(index)
|
||||||
|
|
||||||
# important - make sure we remove from the end so we aren't changing used indices as we go
|
# important - make sure we remove from the end so we aren't changing used indices as we go
|
||||||
field_indices.sort(reverse=True)
|
self.field_indices.sort(reverse=True)
|
||||||
|
|
||||||
# this second time we make a cleaned version of the fields
|
# this second time we make a cleaned version of the fields
|
||||||
for index in field_indices:
|
for index in self.field_indices:
|
||||||
fields.remove(index)
|
fields.remove(index)
|
||||||
|
|
||||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
(self.sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
||||||
fields, source.wkbType(), source.sourceCrs())
|
fields, self.source.wkbType(), self.source.sourceCrs())
|
||||||
|
return True
|
||||||
|
|
||||||
features = source.getFeatures()
|
def processAlgorithm(self, context, feedback):
|
||||||
total = 100.0 / source.featureCount() if source.featureCount() else 0
|
features = self.source.getFeatures()
|
||||||
|
total = 100.0 / self.source.featureCount() if self.source.featureCount() else 0
|
||||||
|
|
||||||
for current, f in enumerate(features):
|
for current, f in enumerate(features):
|
||||||
if feedback.isCanceled():
|
if feedback.isCanceled():
|
||||||
break
|
break
|
||||||
|
|
||||||
attributes = f.attributes()
|
attributes = f.attributes()
|
||||||
for index in field_indices:
|
for index in self.field_indices:
|
||||||
del attributes[index]
|
del attributes[index]
|
||||||
f.setAttributes(attributes)
|
f.setAttributes(attributes)
|
||||||
sink.addFeature(f, QgsFeatureSink.FastInsert)
|
self.sink.addFeature(f, QgsFeatureSink.FastInsert)
|
||||||
|
|
||||||
feedback.setProgress(int(current * total))
|
feedback.setProgress(int(current * total))
|
||||||
|
|
||||||
return {self.OUTPUT: dest_id}
|
return True
|
||||||
|
|
||||||
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
|
return {self.OUTPUT: self.dest_id}
|
||||||
|
@ -58,31 +58,40 @@ class DeleteHoles(QgisAlgorithm):
|
|||||||
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Cleaned'), QgsProcessingParameterDefinition.TypeVectorPolygon))
|
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Cleaned'), QgsProcessingParameterDefinition.TypeVectorPolygon))
|
||||||
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Cleaned'), QgsProcessingParameterDefinition.TypeVectorPolygon))
|
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Cleaned'), QgsProcessingParameterDefinition.TypeVectorPolygon))
|
||||||
|
|
||||||
|
self.source = None
|
||||||
|
self.min_area = None
|
||||||
|
self.sink = None
|
||||||
|
self.dest_id = None
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'deleteholes'
|
return 'deleteholes'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Delete holes')
|
return self.tr('Delete holes')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
source = self.parameterAsSource(parameters, self.INPUT, context)
|
self.source = self.parameterAsSource(parameters, self.INPUT, context)
|
||||||
min_area = self.parameterAsDouble(parameters, self.MIN_AREA, context)
|
self.min_area = self.parameterAsDouble(parameters, self.MIN_AREA, context)
|
||||||
if min_area == 0.0:
|
if self.min_area == 0.0:
|
||||||
min_area = -1.0
|
self.min_area = -1.0
|
||||||
|
|
||||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
(self.sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
||||||
source.fields(), source.wkbType(), source.sourceCrs())
|
self.source.fields(), self.source.wkbType(), self.source.sourceCrs())
|
||||||
|
return True
|
||||||
|
|
||||||
features = source.getFeatures()
|
def processAlgorithm(self, context, feedback):
|
||||||
total = 100.0 / source.featureCount() if source.featureCount() else 0
|
features = self.source.getFeatures()
|
||||||
|
total = 100.0 / self.source.featureCount() if self.source.featureCount() else 0
|
||||||
|
|
||||||
for current, f in enumerate(features):
|
for current, f in enumerate(features):
|
||||||
if feedback.isCanceled():
|
if feedback.isCanceled():
|
||||||
break
|
break
|
||||||
|
|
||||||
if f.hasGeometry():
|
if f.hasGeometry():
|
||||||
f.setGeometry(f.geometry().removeInteriorRings(min_area))
|
f.setGeometry(f.geometry().removeInteriorRings(self.min_area))
|
||||||
sink.addFeature(f, QgsFeatureSink.FastInsert)
|
self.sink.addFeature(f, QgsFeatureSink.FastInsert)
|
||||||
feedback.setProgress(int(current * total))
|
feedback.setProgress(int(current * total))
|
||||||
|
return True
|
||||||
|
|
||||||
return {self.OUTPUT: dest_id}
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
|
return {self.OUTPUT: self.dest_id}
|
||||||
|
@ -63,21 +63,28 @@ class DensifyGeometries(QgisAlgorithm):
|
|||||||
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Densified')))
|
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Densified')))
|
||||||
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Densified')))
|
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Densified')))
|
||||||
|
|
||||||
|
self.source = None
|
||||||
|
self.sink = None
|
||||||
|
self.vertices = None
|
||||||
|
self.dest_id = None
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'densifygeometries'
|
return 'densifygeometries'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Densify geometries')
|
return self.tr('Densify geometries')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
source = self.parameterAsSource(parameters, self.INPUT, context)
|
self.source = self.parameterAsSource(parameters, self.INPUT, context)
|
||||||
vertices = self.parameterAsInt(parameters, self.VERTICES, context)
|
self.vertices = self.parameterAsInt(parameters, self.VERTICES, context)
|
||||||
|
|
||||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
(self.sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
||||||
source.fields(), source.wkbType(), source.sourceCrs())
|
self.source.fields(), self.source.wkbType(), self.source.sourceCrs())
|
||||||
|
return True
|
||||||
|
|
||||||
features = source.getFeatures()
|
def processAlgorithm(self, context, feedback):
|
||||||
total = 100.0 / source.featureCount() if source.featureCount() else 0
|
features = self.source.getFeatures()
|
||||||
|
total = 100.0 / self.source.featureCount() if self.source.featureCount() else 0
|
||||||
|
|
||||||
for current, f in enumerate(features):
|
for current, f in enumerate(features):
|
||||||
if feedback.isCanceled():
|
if feedback.isCanceled():
|
||||||
@ -85,9 +92,11 @@ class DensifyGeometries(QgisAlgorithm):
|
|||||||
|
|
||||||
feature = f
|
feature = f
|
||||||
if feature.hasGeometry():
|
if feature.hasGeometry():
|
||||||
new_geometry = feature.geometry().densifyByCount(vertices)
|
new_geometry = feature.geometry().densifyByCount(self.vertices)
|
||||||
feature.setGeometry(new_geometry)
|
feature.setGeometry(new_geometry)
|
||||||
sink.addFeature(feature, QgsFeatureSink.FastInsert)
|
self.sink.addFeature(feature, QgsFeatureSink.FastInsert)
|
||||||
feedback.setProgress(int(current * total))
|
feedback.setProgress(int(current * total))
|
||||||
|
return True
|
||||||
|
|
||||||
return {self.OUTPUT: dest_id}
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
|
return {self.OUTPUT: self.dest_id}
|
||||||
|
@ -61,31 +61,40 @@ class DensifyGeometriesInterval(QgisAlgorithm):
|
|||||||
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Densified')))
|
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Densified')))
|
||||||
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Densified')))
|
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Densified')))
|
||||||
|
|
||||||
|
self.source = None
|
||||||
|
self.interval = None
|
||||||
|
self.sink = None
|
||||||
|
self.dest_id = None
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'densifygeometriesgivenaninterval'
|
return 'densifygeometriesgivenaninterval'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Densify geometries given an interval')
|
return self.tr('Densify geometries given an interval')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
source = self.parameterAsSource(parameters, self.INPUT, context)
|
self.source = self.parameterAsSource(parameters, self.INPUT, context)
|
||||||
interval = self.parameterAsDouble(parameters, self.INTERVAL, context)
|
self.interval = self.parameterAsDouble(parameters, self.INTERVAL, context)
|
||||||
|
|
||||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
(self.sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
||||||
source.fields(), source.wkbType(), source.sourceCrs())
|
self.source.fields(), self.source.wkbType(), self.source.sourceCrs())
|
||||||
|
return True
|
||||||
|
|
||||||
features = source.getFeatures()
|
def processAlgorithm(self, context, feedback):
|
||||||
total = 100.0 / source.featureCount() if source.featureCount() else 0
|
features = self.source.getFeatures()
|
||||||
|
total = 100.0 / self.source.featureCount() if self.source.featureCount() else 0
|
||||||
for current, f in enumerate(features):
|
for current, f in enumerate(features):
|
||||||
if feedback.isCanceled():
|
if feedback.isCanceled():
|
||||||
break
|
break
|
||||||
|
|
||||||
feature = f
|
feature = f
|
||||||
if feature.hasGeometry():
|
if feature.hasGeometry():
|
||||||
new_geometry = feature.geometry().densifyByDistance(float(interval))
|
new_geometry = feature.geometry().densifyByDistance(float(self.interval))
|
||||||
feature.setGeometry(new_geometry)
|
feature.setGeometry(new_geometry)
|
||||||
sink.addFeature(feature, QgsFeatureSink.FastInsert)
|
self.sink.addFeature(feature, QgsFeatureSink.FastInsert)
|
||||||
|
|
||||||
feedback.setProgress(int(current * total))
|
feedback.setProgress(int(current * total))
|
||||||
|
return True
|
||||||
|
|
||||||
return {self.OUTPUT: dest_id}
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
|
return {self.OUTPUT: self.dest_id}
|
||||||
|
@ -39,8 +39,8 @@ from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
|||||||
|
|
||||||
class DropGeometry(QgisAlgorithm):
|
class DropGeometry(QgisAlgorithm):
|
||||||
|
|
||||||
INPUT_LAYER = 'INPUT_LAYER'
|
INPUT = 'INPUT'
|
||||||
OUTPUT_TABLE = 'OUTPUT_TABLE'
|
OUTPUT = 'OUTPUT'
|
||||||
|
|
||||||
def tags(self):
|
def tags(self):
|
||||||
return self.tr('remove,drop,delete,geometry,objects').split(',')
|
return self.tr('remove,drop,delete,geometry,objects').split(',')
|
||||||
@ -51,9 +51,13 @@ class DropGeometry(QgisAlgorithm):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT_LAYER, self.tr('Input layer'), [QgsProcessingParameterDefinition.TypeVectorPoint, QgsProcessingParameterDefinition.TypeVectorLine, QgsProcessingParameterDefinition.TypeVectorPolygon]))
|
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT, self.tr('Input layer'), [QgsProcessingParameterDefinition.TypeVectorPoint, QgsProcessingParameterDefinition.TypeVectorLine, QgsProcessingParameterDefinition.TypeVectorPolygon]))
|
||||||
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT_TABLE, self.tr('Dropped geometry')))
|
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Dropped geometry')))
|
||||||
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT_TABLE, self.tr("Dropped geometry")))
|
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr("Dropped geometry")))
|
||||||
|
|
||||||
|
self.source = None
|
||||||
|
self.sink = None
|
||||||
|
self.dest_id = None
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'dropgeometries'
|
return 'dropgeometries'
|
||||||
@ -61,21 +65,26 @@ class DropGeometry(QgisAlgorithm):
|
|||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Drop geometries')
|
return self.tr('Drop geometries')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
source = self.parameterAsSource(parameters, self.INPUT_LAYER, context)
|
self.source = self.parameterAsSource(parameters, self.INPUT, context)
|
||||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT_TABLE, context,
|
(self.sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
||||||
source.fields(), QgsWkbTypes.NoGeometry, QgsCoordinateReferenceSystem())
|
self.source.fields(), QgsWkbTypes.NoGeometry, QgsCoordinateReferenceSystem())
|
||||||
|
return True
|
||||||
|
|
||||||
|
def processAlgorithm(self, context, feedback):
|
||||||
request = QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry)
|
request = QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry)
|
||||||
features = source.getFeatures(request)
|
features = self.source.getFeatures(request)
|
||||||
total = 100.0 / source.featureCount() if source.featureCount() else 0
|
total = 100.0 / self.source.featureCount() if self.source.featureCount() else 0
|
||||||
|
|
||||||
for current, input_feature in enumerate(features):
|
for current, input_feature in enumerate(features):
|
||||||
if feedback.isCanceled():
|
if feedback.isCanceled():
|
||||||
break
|
break
|
||||||
|
|
||||||
input_feature.clearGeometry()
|
input_feature.clearGeometry()
|
||||||
sink.addFeature(input_feature, QgsFeatureSink.FastInsert)
|
self.sink.addFeature(input_feature, QgsFeatureSink.FastInsert)
|
||||||
feedback.setProgress(int(current * total))
|
feedback.setProgress(int(current * total))
|
||||||
|
|
||||||
return {self.OUTPUT_TABLE: dest_id}
|
return True
|
||||||
|
|
||||||
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
|
return {self.OUTPUT: self.dest_id}
|
||||||
|
@ -79,15 +79,20 @@ class ExtentFromLayer(QgisAlgorithm):
|
|||||||
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Extent')))
|
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Extent')))
|
||||||
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr("Extent"), QgsProcessingParameterDefinition.TypeVectorPolygon))
|
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr("Extent"), QgsProcessingParameterDefinition.TypeVectorPolygon))
|
||||||
|
|
||||||
|
self.source = None
|
||||||
|
self.byFeature = None
|
||||||
|
self.sink = None
|
||||||
|
self.dest_id = None
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'polygonfromlayerextent'
|
return 'polygonfromlayerextent'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Polygon from layer extent')
|
return self.tr('Polygon from layer extent')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
source = self.parameterAsSource(parameters, self.INPUT_LAYER, context)
|
self.source = self.parameterAsSource(parameters, self.INPUT_LAYER, context)
|
||||||
byFeature = self.parameterAsBool(parameters, self.BY_FEATURE, context)
|
self.byFeature = self.parameterAsBool(parameters, self.BY_FEATURE, context)
|
||||||
|
|
||||||
fields = QgsFields()
|
fields = QgsFields()
|
||||||
fields.append(QgsField('MINX', QVariant.Double))
|
fields.append(QgsField('MINX', QVariant.Double))
|
||||||
@ -101,15 +106,19 @@ class ExtentFromLayer(QgisAlgorithm):
|
|||||||
fields.append(QgsField('HEIGHT', QVariant.Double))
|
fields.append(QgsField('HEIGHT', QVariant.Double))
|
||||||
fields.append(QgsField('WIDTH', QVariant.Double))
|
fields.append(QgsField('WIDTH', QVariant.Double))
|
||||||
|
|
||||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
(self.sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
||||||
fields, QgsWkbTypes.Polygon, source.sourceCrs())
|
fields, QgsWkbTypes.Polygon, self.source.sourceCrs())
|
||||||
|
return True
|
||||||
|
|
||||||
if byFeature:
|
def processAlgorithm(self, context, feedback):
|
||||||
self.featureExtent(source, context, sink, feedback)
|
if self.byFeature:
|
||||||
|
self.featureExtent(self.source, context, self.sink, feedback)
|
||||||
else:
|
else:
|
||||||
self.layerExtent(source, sink, feedback)
|
self.layerExtent(self.source, self.sink, feedback)
|
||||||
|
return True
|
||||||
|
|
||||||
return {self.OUTPUT: dest_id}
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
|
return {self.OUTPUT: self.dest_id}
|
||||||
|
|
||||||
def layerExtent(self, source, sink, feedback):
|
def layerExtent(self, source, sink, feedback):
|
||||||
rect = source.sourceExtent()
|
rect = source.sourceExtent()
|
||||||
|
@ -55,20 +55,26 @@ class FixGeometry(QgisAlgorithm):
|
|||||||
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Fixed geometries')))
|
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Fixed geometries')))
|
||||||
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr("Fixed geometries")))
|
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr("Fixed geometries")))
|
||||||
|
|
||||||
|
self.source = None
|
||||||
|
self.sink = None
|
||||||
|
self.dest_id = None
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'fixgeometries'
|
return 'fixgeometries'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Fix geometries')
|
return self.tr('Fix geometries')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
source = self.parameterAsSource(parameters, self.INPUT, context)
|
self.source = self.parameterAsSource(parameters, self.INPUT, context)
|
||||||
|
|
||||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
(self.sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
||||||
source.fields(), QgsWkbTypes.multiType(source.wkbType()), source.sourceCrs())
|
self.source.fields(), QgsWkbTypes.multiType(self.source.wkbType()), self.source.sourceCrs())
|
||||||
|
return True
|
||||||
|
|
||||||
features = source.getFeatures(QgsFeatureRequest(), QgsProcessingFeatureSource.FlagSkipGeometryValidityChecks)
|
def processAlgorithm(self, context, feedback):
|
||||||
total = 100.0 / source.featureCount() if source.featureCount() else 0
|
features = self.source.getFeatures(QgsFeatureRequest(), QgsProcessingFeatureSource.FlagSkipGeometryValidityChecks)
|
||||||
|
total = 100.0 / self.source.featureCount() if self.source.featureCount() else 0
|
||||||
for current, inputFeature in enumerate(features):
|
for current, inputFeature in enumerate(features):
|
||||||
if feedback.isCanceled():
|
if feedback.isCanceled():
|
||||||
break
|
break
|
||||||
@ -86,7 +92,7 @@ class FixGeometry(QgisAlgorithm):
|
|||||||
try:
|
try:
|
||||||
g.convertToMultiType()
|
g.convertToMultiType()
|
||||||
outputFeature.setGeometry(QgsGeometry(g))
|
outputFeature.setGeometry(QgsGeometry(g))
|
||||||
sink.addFeature(outputFeature, QgsFeatureSink.FastInsert)
|
self.sink.addFeature(outputFeature, QgsFeatureSink.FastInsert)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
feedback.setProgress(int(current * total))
|
feedback.setProgress(int(current * total))
|
||||||
@ -95,7 +101,9 @@ class FixGeometry(QgisAlgorithm):
|
|||||||
outputGeometry.convertToMultiType()
|
outputGeometry.convertToMultiType()
|
||||||
outputFeature.setGeometry(outputGeometry)
|
outputFeature.setGeometry(outputGeometry)
|
||||||
|
|
||||||
sink.addFeature(outputFeature, QgsFeatureSink.FastInsert)
|
self.sink.addFeature(outputFeature, QgsFeatureSink.FastInsert)
|
||||||
feedback.setProgress(int(current * total))
|
feedback.setProgress(int(current * total))
|
||||||
|
return True
|
||||||
|
|
||||||
return {self.OUTPUT: dest_id}
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
|
return {self.OUTPUT: self.dest_id}
|
||||||
|
@ -102,41 +102,52 @@ class GridPolygon(QgisAlgorithm):
|
|||||||
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Grid')))
|
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Grid')))
|
||||||
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Grid'), QgsProcessingParameterDefinition.TypeVectorPolygon))
|
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Grid'), QgsProcessingParameterDefinition.TypeVectorPolygon))
|
||||||
|
|
||||||
|
self.idx = None
|
||||||
|
self.hSpacing = None
|
||||||
|
self.vSpacing = None
|
||||||
|
self.hOverlay = None
|
||||||
|
self.vOverlay = None
|
||||||
|
self.width = None
|
||||||
|
self.height = None
|
||||||
|
self.originX = None
|
||||||
|
self.originY = None
|
||||||
|
self.sink = None
|
||||||
|
self.dest_id = None
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'creategridpolygon'
|
return 'creategridpolygon'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Create grid (polygon)')
|
return self.tr('Create grid (polygon)')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
idx = self.parameterAsEnum(parameters, self.TYPE, context)
|
self.idx = self.parameterAsEnum(parameters, self.TYPE, context)
|
||||||
|
|
||||||
hSpacing = self.parameterAsDouble(parameters, self.HSPACING, context)
|
self.hSpacing = self.parameterAsDouble(parameters, self.HSPACING, context)
|
||||||
vSpacing = self.parameterAsDouble(parameters, self.VSPACING, context)
|
self.vSpacing = self.parameterAsDouble(parameters, self.VSPACING, context)
|
||||||
hOverlay = self.parameterAsDouble(parameters, self.HOVERLAY, context)
|
self.hOverlay = self.parameterAsDouble(parameters, self.HOVERLAY, context)
|
||||||
vOverlay = self.parameterAsDouble(parameters, self.VOVERLAY, context)
|
self.vOverlay = self.parameterAsDouble(parameters, self.VOVERLAY, context)
|
||||||
|
|
||||||
bbox = self.parameterAsExtent(parameters, self.EXTENT, context)
|
bbox = self.parameterAsExtent(parameters, self.EXTENT, context)
|
||||||
crs = self.parameterAsCrs(parameters, self.CRS, context)
|
crs = self.parameterAsCrs(parameters, self.CRS, context)
|
||||||
|
self.width = bbox.width()
|
||||||
|
self.height = bbox.height()
|
||||||
|
self.originX = bbox.xMinimum()
|
||||||
|
self.originY = bbox.yMaximum()
|
||||||
|
|
||||||
width = bbox.width()
|
if self.hSpacing <= 0 or self.vSpacing <= 0:
|
||||||
height = bbox.height()
|
|
||||||
originX = bbox.xMinimum()
|
|
||||||
originY = bbox.yMaximum()
|
|
||||||
|
|
||||||
if hSpacing <= 0 or vSpacing <= 0:
|
|
||||||
raise GeoAlgorithmExecutionException(
|
raise GeoAlgorithmExecutionException(
|
||||||
self.tr('Invalid grid spacing: {0}/{1}').format(hSpacing, vSpacing))
|
self.tr('Invalid grid spacing: {0}/{1}').format(self.hSpacing, self.vSpacing))
|
||||||
|
|
||||||
if width < hSpacing:
|
if self.width < self.hSpacing:
|
||||||
raise GeoAlgorithmExecutionException(
|
raise GeoAlgorithmExecutionException(
|
||||||
self.tr('Horizontal spacing is too small for the covered area'))
|
self.tr('Horizontal spacing is too small for the covered area'))
|
||||||
|
|
||||||
if hSpacing <= hOverlay or vSpacing <= vOverlay:
|
if self.hSpacing <= self.hOverlay or self.vSpacing <= self.vOverlay:
|
||||||
raise GeoAlgorithmExecutionException(
|
raise GeoAlgorithmExecutionException(
|
||||||
self.tr('Invalid overlay: {0}/{1}').format(hOverlay, vOverlay))
|
self.tr('Invalid overlay: {0}/{1}').format(self.hOverlay, self.vOverlay))
|
||||||
|
|
||||||
if height < vSpacing:
|
if self.height < self.vSpacing:
|
||||||
raise GeoAlgorithmExecutionException(
|
raise GeoAlgorithmExecutionException(
|
||||||
self.tr('Vertical spacing is too small for the covered area'))
|
self.tr('Vertical spacing is too small for the covered area'))
|
||||||
|
|
||||||
@ -147,20 +158,24 @@ class GridPolygon(QgisAlgorithm):
|
|||||||
fields.append(QgsField('bottom', QVariant.Double, '', 24, 16))
|
fields.append(QgsField('bottom', QVariant.Double, '', 24, 16))
|
||||||
fields.append(QgsField('id', QVariant.Int, '', 10, 0))
|
fields.append(QgsField('id', QVariant.Int, '', 10, 0))
|
||||||
|
|
||||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
(self.sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
||||||
fields, QgsWkbTypes.Polygon, crs)
|
fields, QgsWkbTypes.Polygon, crs)
|
||||||
|
return True
|
||||||
|
|
||||||
if idx == 0:
|
def processAlgorithm(self, context, feedback):
|
||||||
|
if self.idx == 0:
|
||||||
self._rectangleGrid(
|
self._rectangleGrid(
|
||||||
sink, width, height, originX, originY, hSpacing, vSpacing, hOverlay, vOverlay, feedback)
|
self.sink, self.width, self.height, self.originX, self.originY, self.hSpacing, self.vSpacing, self.hOverlay, self.vOverlay, feedback)
|
||||||
elif idx == 1:
|
elif self.idx == 1:
|
||||||
self._diamondGrid(
|
self._diamondGrid(
|
||||||
sink, width, height, originX, originY, hSpacing, vSpacing, hOverlay, vOverlay, feedback)
|
self.sink, self.width, self.height, self.originX, self.originY, self.hSpacing, self.vSpacing, self.hOverlay, self.vOverlay, feedback)
|
||||||
elif idx == 2:
|
elif self.idx == 2:
|
||||||
self._hexagonGrid(
|
self._hexagonGrid(
|
||||||
sink, width, height, originX, originY, hSpacing, vSpacing, hOverlay, vOverlay, feedback)
|
self.sink, self.width, self.height, self.originX, self.originY, self.hSpacing, self.vSpacing, self.hOverlay, self.vOverlay, feedback)
|
||||||
|
return True
|
||||||
|
|
||||||
return {self.OUTPUT: dest_id}
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
|
return {self.OUTPUT: self.dest_id}
|
||||||
|
|
||||||
def _rectangleGrid(self, sink, width, height, originX, originY,
|
def _rectangleGrid(self, sink, width, height, originX, originY,
|
||||||
hSpacing, vSpacing, hOverlay, vOverlay, feedback):
|
hSpacing, vSpacing, hOverlay, vOverlay, feedback):
|
||||||
|
@ -27,9 +27,7 @@ __revision__ = '$Format:%H$'
|
|||||||
|
|
||||||
from qgis.core import (QgsVectorLayerExporter,
|
from qgis.core import (QgsVectorLayerExporter,
|
||||||
QgsSettings,
|
QgsSettings,
|
||||||
QgsApplication,
|
|
||||||
QgsFeatureSink,
|
QgsFeatureSink,
|
||||||
QgsProcessingUtils,
|
|
||||||
QgsProcessingParameterFeatureSource,
|
QgsProcessingParameterFeatureSource,
|
||||||
QgsProcessingParameterString,
|
QgsProcessingParameterString,
|
||||||
QgsProcessingParameterField,
|
QgsProcessingParameterField,
|
||||||
@ -38,10 +36,6 @@ from qgis.core import (QgsVectorLayerExporter,
|
|||||||
|
|
||||||
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
||||||
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
|
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
|
||||||
from processing.core.parameters import ParameterBoolean
|
|
||||||
from processing.core.parameters import ParameterVector
|
|
||||||
from processing.core.parameters import ParameterString
|
|
||||||
from processing.core.parameters import ParameterTableField
|
|
||||||
from processing.tools import postgis
|
from processing.tools import postgis
|
||||||
|
|
||||||
|
|
||||||
@ -112,70 +106,86 @@ class ImportIntoPostGIS(QgisAlgorithm):
|
|||||||
self.addParameter(QgsProcessingParameterBoolean(self.FORCE_SINGLEPART,
|
self.addParameter(QgsProcessingParameterBoolean(self.FORCE_SINGLEPART,
|
||||||
self.tr('Create single-part geometries instead of multi-part'), False))
|
self.tr('Create single-part geometries instead of multi-part'), False))
|
||||||
|
|
||||||
|
self.db = None
|
||||||
|
self.schema = None
|
||||||
|
self.overwrite = None
|
||||||
|
self.createIndex = None
|
||||||
|
self.convertLowerCase = None
|
||||||
|
self.dropStringLength = None
|
||||||
|
self.forceSinglePart = None
|
||||||
|
self.primaryKeyField = None
|
||||||
|
self.encoding = None
|
||||||
|
self.source = None
|
||||||
|
self.table = None
|
||||||
|
self.providerName = None
|
||||||
|
self.geomColumn = None
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'importintopostgis'
|
return 'importintopostgis'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Import into PostGIS')
|
return self.tr('Import into PostGIS')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
connection = self.parameterAsString(parameters, self.DATABASE, context)
|
connection = self.parameterAsString(parameters, self.DATABASE, context)
|
||||||
db = postgis.GeoDB.from_name(connection)
|
self.db = postgis.GeoDB.from_name(connection)
|
||||||
|
|
||||||
schema = self.parameterAsString(parameters, self.SCHEMA, context)
|
self.schema = self.parameterAsString(parameters, self.SCHEMA, context)
|
||||||
overwrite = self.parameterAsBool(parameters, self.OVERWRITE, context)
|
self.overwrite = self.parameterAsBool(parameters, self.OVERWRITE, context)
|
||||||
createIndex = self.parameterAsBool(parameters, self.CREATEINDEX, context)
|
self.createIndex = self.parameterAsBool(parameters, self.CREATEINDEX, context)
|
||||||
convertLowerCase = self.parameterAsBool(parameters, self.LOWERCASE_NAMES, context)
|
self.convertLowerCase = self.parameterAsBool(parameters, self.LOWERCASE_NAMES, context)
|
||||||
dropStringLength = self.parameterAsBool(parameters, self.DROP_STRING_LENGTH, context)
|
self.dropStringLength = self.parameterAsBool(parameters, self.DROP_STRING_LENGTH, context)
|
||||||
forceSinglePart = self.parameterAsBool(parameters, self.FORCE_SINGLEPART, context)
|
self.forceSinglePart = self.parameterAsBool(parameters, self.FORCE_SINGLEPART, context)
|
||||||
primaryKeyField = self.parameterAsString(parameters, self.PRIMARY_KEY, context) or 'id'
|
self.primaryKeyField = self.parameterAsString(parameters, self.PRIMARY_KEY, context) or 'id'
|
||||||
encoding = self.parameterAsString(parameters, self.ENCODING, context)
|
self.encoding = self.parameterAsString(parameters, self.ENCODING, context)
|
||||||
|
|
||||||
source = self.parameterAsSource(parameters, self.INPUT, context)
|
self.source = self.parameterAsSource(parameters, self.INPUT, context)
|
||||||
|
|
||||||
table = self.parameterAsString(parameters, self.TABLENAME, context)
|
self.table = self.parameterAsString(parameters, self.TABLENAME, context)
|
||||||
if table:
|
if self.table:
|
||||||
table.strip()
|
self.table.strip()
|
||||||
if not table or table == '':
|
if not self.table or self.table == '':
|
||||||
table = source.sourceName()
|
self.table = self.source.sourceName()
|
||||||
table = table.replace('.', '_')
|
self.table = self.table.replace('.', '_')
|
||||||
table = table.replace(' ', '').lower()[0:62]
|
self.table = self.table.replace(' ', '').lower()[0:62]
|
||||||
providerName = 'postgres'
|
self.providerName = 'postgres'
|
||||||
|
|
||||||
geomColumn = self.parameterAsString(parameters, self.GEOMETRY_COLUMN, context)
|
self.geomColumn = self.parameterAsString(parameters, self.GEOMETRY_COLUMN, context)
|
||||||
if not geomColumn:
|
if not self.geomColumn:
|
||||||
geomColumn = 'geom'
|
self.geomColumn = 'geom'
|
||||||
|
return True
|
||||||
|
|
||||||
|
def processAlgorithm(self, context, feedback):
|
||||||
options = {}
|
options = {}
|
||||||
if overwrite:
|
if self.overwrite:
|
||||||
options['overwrite'] = True
|
options['overwrite'] = True
|
||||||
if convertLowerCase:
|
if self.convertLowerCase:
|
||||||
options['lowercaseFieldNames'] = True
|
options['lowercaseFieldNames'] = True
|
||||||
geomColumn = geomColumn.lower()
|
self.geomColumn = self.geomColumn.lower()
|
||||||
if dropStringLength:
|
if self.dropStringLength:
|
||||||
options['dropStringConstraints'] = True
|
options['dropStringConstraints'] = True
|
||||||
if forceSinglePart:
|
if self.forceSinglePart:
|
||||||
options['forceSinglePartGeometryType'] = True
|
options['forceSinglePartGeometryType'] = True
|
||||||
|
|
||||||
# Clear geometry column for non-geometry tables
|
# Clear geometry column for non-geometry tables
|
||||||
if source.wkbType() == QgsWkbTypes.NoGeometry:
|
if self.source.wkbType() == QgsWkbTypes.NoGeometry:
|
||||||
geomColumn = None
|
self.geomColumn = None
|
||||||
|
|
||||||
uri = db.uri
|
uri = self.db.uri
|
||||||
uri.setDataSource(schema, table, geomColumn, '', primaryKeyField)
|
uri.setDataSource(self.schema, self.table, self.geomColumn, '', self.primaryKeyField)
|
||||||
|
|
||||||
if encoding:
|
if self.encoding:
|
||||||
options['fileEncoding'] = encoding
|
options['fileEncoding'] = self.encoding
|
||||||
|
|
||||||
exporter = QgsVectorLayerExporter(uri.uri(), providerName, source.fields(),
|
exporter = QgsVectorLayerExporter(uri.uri(), self.providerName, self.source.fields(),
|
||||||
source.wkbType(), source.sourceCrs(), overwrite, options)
|
self.source.wkbType(), self.source.sourceCrs(), self.overwrite, options)
|
||||||
|
|
||||||
if exporter.errorCode() != QgsVectorLayerExporter.NoError:
|
if exporter.errorCode() != QgsVectorLayerExporter.NoError:
|
||||||
raise GeoAlgorithmExecutionException(
|
raise GeoAlgorithmExecutionException(
|
||||||
self.tr('Error importing to PostGIS\n{0}').format(exporter.errorMessage()))
|
self.tr('Error importing to PostGIS\n{0}').format(exporter.errorMessage()))
|
||||||
|
|
||||||
features = source.getFeatures()
|
features = self.source.getFeatures()
|
||||||
total = 100.0 / source.featureCount() if source.featureCount() else 0
|
total = 100.0 / self.source.featureCount() if self.source.featureCount() else 0
|
||||||
for current, f in enumerate(features):
|
for current, f in enumerate(features):
|
||||||
if feedback.isCanceled():
|
if feedback.isCanceled():
|
||||||
break
|
break
|
||||||
@ -190,11 +200,13 @@ class ImportIntoPostGIS(QgisAlgorithm):
|
|||||||
raise GeoAlgorithmExecutionException(
|
raise GeoAlgorithmExecutionException(
|
||||||
self.tr('Error importing to PostGIS\n{0}').format(exporter.errorMessage()))
|
self.tr('Error importing to PostGIS\n{0}').format(exporter.errorMessage()))
|
||||||
|
|
||||||
if geomColumn and createIndex:
|
if self.geomColumn and self.createIndex:
|
||||||
db.create_spatial_index(table, schema, geomColumn)
|
self.db.create_spatial_index(self.table, self.schema, self.geomColumn)
|
||||||
|
|
||||||
db.vacuum_analyze(table, schema)
|
self.db.vacuum_analyze(self.table, self.schema)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
def dbConnectionNames(self):
|
def dbConnectionNames(self):
|
||||||
|
@ -28,8 +28,6 @@ __revision__ = '$Format:%H$'
|
|||||||
from qgis.core import (QgsDataSourceUri,
|
from qgis.core import (QgsDataSourceUri,
|
||||||
QgsFeatureSink,
|
QgsFeatureSink,
|
||||||
QgsVectorLayerExporter,
|
QgsVectorLayerExporter,
|
||||||
QgsApplication,
|
|
||||||
QgsProcessingUtils,
|
|
||||||
QgsProcessingParameterFeatureSource,
|
QgsProcessingParameterFeatureSource,
|
||||||
QgsProcessingParameterVectorLayer,
|
QgsProcessingParameterVectorLayer,
|
||||||
QgsProcessingParameterField,
|
QgsProcessingParameterField,
|
||||||
@ -73,13 +71,26 @@ class ImportIntoSpatialite(QgisAlgorithm):
|
|||||||
self.addParameter(QgsProcessingParameterBoolean(self.DROP_STRING_LENGTH, self.tr('Drop length constraints on character fields'), False))
|
self.addParameter(QgsProcessingParameterBoolean(self.DROP_STRING_LENGTH, self.tr('Drop length constraints on character fields'), False))
|
||||||
self.addParameter(QgsProcessingParameterBoolean(self.FORCE_SINGLEPART, self.tr('Create single-part geometries instead of multi-part'), False))
|
self.addParameter(QgsProcessingParameterBoolean(self.FORCE_SINGLEPART, self.tr('Create single-part geometries instead of multi-part'), False))
|
||||||
|
|
||||||
|
self.db = None
|
||||||
|
self.overwrite = None
|
||||||
|
self.createIndex = None
|
||||||
|
self.dropStringLength = None
|
||||||
|
self.convertLowerCase = None
|
||||||
|
self.forceSinglePart = None
|
||||||
|
self.primaryKeyField = None
|
||||||
|
self.encoding = None
|
||||||
|
self.source = None
|
||||||
|
self.table = None
|
||||||
|
self.providerName = None
|
||||||
|
self.geomColumn = None
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'importintospatialite'
|
return 'importintospatialite'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Import into Spatialite')
|
return self.tr('Import into Spatialite')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
database = self.parameterAsVectorLayer(parameters, self.DATABASE, context)
|
database = self.parameterAsVectorLayer(parameters, self.DATABASE, context)
|
||||||
databaseuri = database.dataProvider().dataSourceUri()
|
databaseuri = database.dataProvider().dataSourceUri()
|
||||||
uri = QgsDataSourceUri(databaseuri)
|
uri = QgsDataSourceUri(databaseuri)
|
||||||
@ -87,61 +98,64 @@ class ImportIntoSpatialite(QgisAlgorithm):
|
|||||||
if '|layerid' in databaseuri:
|
if '|layerid' in databaseuri:
|
||||||
databaseuri = databaseuri[:databaseuri.find('|layerid')]
|
databaseuri = databaseuri[:databaseuri.find('|layerid')]
|
||||||
uri = QgsDataSourceUri('dbname=\'%s\'' % (databaseuri))
|
uri = QgsDataSourceUri('dbname=\'%s\'' % (databaseuri))
|
||||||
db = spatialite.GeoDB(uri)
|
self.db = spatialite.GeoDB(uri)
|
||||||
|
|
||||||
overwrite = self.parameterAsBool(parameters, self.OVERWRITE, context)
|
self.overwrite = self.parameterAsBool(parameters, self.OVERWRITE, context)
|
||||||
createIndex = self.parameterAsBool(parameters, self.CREATEINDEX, context)
|
self.createIndex = self.parameterAsBool(parameters, self.CREATEINDEX, context)
|
||||||
convertLowerCase = self.parameterAsBool(parameters, self.LOWERCASE_NAMES, context)
|
self.convertLowerCase = self.parameterAsBool(parameters, self.LOWERCASE_NAMES, context)
|
||||||
dropStringLength = self.parameterAsBool(parameters, self.DROP_STRING_LENGTH, context)
|
self.dropStringLength = self.parameterAsBool(parameters, self.DROP_STRING_LENGTH, context)
|
||||||
forceSinglePart = self.parameterAsBool(parameters, self.FORCE_SINGLEPART, context)
|
self.forceSinglePart = self.parameterAsBool(parameters, self.FORCE_SINGLEPART, context)
|
||||||
primaryKeyField = self.parameterAsString(parameters, self.PRIMARY_KEY, context) or 'id'
|
self.primaryKeyField = self.parameterAsString(parameters, self.PRIMARY_KEY, context) or 'id'
|
||||||
encoding = self.parameterAsString(parameters, self.ENCODING, context)
|
self.encoding = self.parameterAsString(parameters, self.ENCODING, context)
|
||||||
|
|
||||||
source = self.parameterAsSource(parameters, self.INPUT, context)
|
self.source = self.parameterAsSource(parameters, self.INPUT, context)
|
||||||
|
|
||||||
table = self.parameterAsString(parameters, self.TABLENAME, context)
|
self.table = self.parameterAsString(parameters, self.TABLENAME, context)
|
||||||
if table:
|
if self.table:
|
||||||
table.strip()
|
self.table.strip()
|
||||||
if not table or table == '':
|
if not self.table or self.table == '':
|
||||||
table = source.sourceName()
|
self.table = self.source.sourceName()
|
||||||
table = table.replace('.', '_')
|
self.table = self.table.replace('.', '_')
|
||||||
table = table.replace(' ', '').lower()
|
self.table = self.table.replace(' ', '').lower()
|
||||||
providerName = 'spatialite'
|
self.providerName = 'spatialite'
|
||||||
|
|
||||||
geomColumn = self.parameterAsString(parameters, self.GEOMETRY_COLUMN, context)
|
self.geomColumn = self.parameterAsString(parameters, self.GEOMETRY_COLUMN, context)
|
||||||
if not geomColumn:
|
if not self.geomColumn:
|
||||||
geomColumn = 'geom'
|
self.geomColumn = 'geom'
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def processAlgorithm(self, context, feedback):
|
||||||
options = {}
|
options = {}
|
||||||
if overwrite:
|
if self.overwrite:
|
||||||
options['overwrite'] = True
|
options['overwrite'] = True
|
||||||
if convertLowerCase:
|
if self.convertLowerCase:
|
||||||
options['lowercaseFieldNames'] = True
|
options['lowercaseFieldNames'] = True
|
||||||
geomColumn = geomColumn.lower()
|
self.geomColumn = self.geomColumn.lower()
|
||||||
if dropStringLength:
|
if self.dropStringLength:
|
||||||
options['dropStringConstraints'] = True
|
options['dropStringConstraints'] = True
|
||||||
if forceSinglePart:
|
if self.forceSinglePart:
|
||||||
options['forceSinglePartGeometryType'] = True
|
options['forceSinglePartGeometryType'] = True
|
||||||
|
|
||||||
# Clear geometry column for non-geometry tables
|
# Clear geometry column for non-geometry tables
|
||||||
if source.wkbType() == QgsWkbTypes.NoGeometry:
|
if self.source.wkbType() == QgsWkbTypes.NoGeometry:
|
||||||
geomColumn = None
|
self.geomColumn = None
|
||||||
|
|
||||||
uri = db.uri
|
uri = self.db.uri
|
||||||
uri.setDataSource('', table, geomColumn, '', primaryKeyField)
|
uri.setDataSource('', self.table, self.geomColumn, '', self.primaryKeyField)
|
||||||
|
|
||||||
if encoding:
|
if self.encoding:
|
||||||
options['fileEncoding'] = encoding
|
options['fileEncoding'] = self.encoding
|
||||||
|
|
||||||
exporter = QgsVectorLayerExporter(uri.uri(), providerName, source.fields(),
|
exporter = QgsVectorLayerExporter(uri.uri(), self.providerName, self.source.fields(),
|
||||||
source.wkbType(), source.sourceCrs(), overwrite, options)
|
self.source.wkbType(), self.source.sourceCrs(), self.overwrite, options)
|
||||||
|
|
||||||
if exporter.errorCode() != QgsVectorLayerExporter.NoError:
|
if exporter.errorCode() != QgsVectorLayerExporter.NoError:
|
||||||
raise GeoAlgorithmExecutionException(
|
raise GeoAlgorithmExecutionException(
|
||||||
self.tr('Error importing to Spatialite\n{0}').format(exporter.errorMessage()))
|
self.tr('Error importing to Spatialite\n{0}').format(exporter.errorMessage()))
|
||||||
|
|
||||||
features = source.getFeatures()
|
features = self.source.getFeatures()
|
||||||
total = 100.0 / source.featureCount() if source.featureCount() else 0
|
total = 100.0 / self.source.featureCount() if self.source.featureCount() else 0
|
||||||
for current, f in enumerate(features):
|
for current, f in enumerate(features):
|
||||||
if feedback.isCanceled():
|
if feedback.isCanceled():
|
||||||
break
|
break
|
||||||
@ -156,7 +170,9 @@ class ImportIntoSpatialite(QgisAlgorithm):
|
|||||||
raise GeoAlgorithmExecutionException(
|
raise GeoAlgorithmExecutionException(
|
||||||
self.tr('Error importing to Spatialite\n{0}').format(exporter.errorMessage()))
|
self.tr('Error importing to Spatialite\n{0}').format(exporter.errorMessage()))
|
||||||
|
|
||||||
if geomColumn and createIndex:
|
if self.geomColumn and self.createIndex:
|
||||||
db.create_spatial_index(table, geomColumn)
|
self.db.create_spatial_index(self.table, self.geomColumn)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
return {}
|
return {}
|
||||||
|
@ -68,19 +68,26 @@ class Merge(QgisAlgorithm):
|
|||||||
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Merged')))
|
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Merged')))
|
||||||
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Merged')))
|
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Merged')))
|
||||||
|
|
||||||
|
self.input_layers = []
|
||||||
|
self.fields = None
|
||||||
|
self.add_layer_field = None
|
||||||
|
self.add_path_field = None
|
||||||
|
self.sink = None
|
||||||
|
self.dest_id = None
|
||||||
|
self.dest_crs = None
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'mergevectorlayers'
|
return 'mergevectorlayers'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Merge vector layers')
|
return self.tr('Merge vector layers')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
input_layers = self.parameterAsLayerList(parameters, self.LAYERS, context)
|
self.input_layers = self.parameterAsLayerList(parameters, self.LAYERS, context)
|
||||||
|
|
||||||
layers = []
|
layers = []
|
||||||
fields = QgsFields()
|
self.fields = QgsFields()
|
||||||
totalFeatureCount = 0
|
totalFeatureCount = 0
|
||||||
for layer in input_layers:
|
for layer in self.input_layers:
|
||||||
if layer.type() != QgsMapLayer.VectorLayer:
|
if layer.type() != QgsMapLayer.VectorLayer:
|
||||||
raise GeoAlgorithmExecutionException(
|
raise GeoAlgorithmExecutionException(
|
||||||
self.tr('All layers must be vector layers!'))
|
self.tr('All layers must be vector layers!'))
|
||||||
@ -95,7 +102,7 @@ class Merge(QgisAlgorithm):
|
|||||||
|
|
||||||
for sindex, sfield in enumerate(layer.fields()):
|
for sindex, sfield in enumerate(layer.fields()):
|
||||||
found = None
|
found = None
|
||||||
for dfield in fields:
|
for dfield in self.fields:
|
||||||
if (dfield.name().upper() == sfield.name().upper()):
|
if (dfield.name().upper() == sfield.name().upper()):
|
||||||
found = dfield
|
found = dfield
|
||||||
if (dfield.type() != sfield.type()):
|
if (dfield.type() != sfield.type()):
|
||||||
@ -104,35 +111,38 @@ class Merge(QgisAlgorithm):
|
|||||||
'data type than in other layers.'.format(sfield.name(), layerSource)))
|
'data type than in other layers.'.format(sfield.name(), layerSource)))
|
||||||
|
|
||||||
if not found:
|
if not found:
|
||||||
fields.append(sfield)
|
self.fields.append(sfield)
|
||||||
|
|
||||||
add_layer_field = False
|
self.add_layer_field = False
|
||||||
if fields.lookupField('layer') < 0:
|
if self.fields.lookupField('layer') < 0:
|
||||||
fields.append(QgsField('layer', QVariant.String, '', 100))
|
self.fields.append(QgsField('layer', QVariant.String, '', 100))
|
||||||
add_layer_field = True
|
self.add_layer_field = True
|
||||||
add_path_field = False
|
self.add_path_field = False
|
||||||
if fields.lookupField('path') < 0:
|
if self.fields.lookupField('path') < 0:
|
||||||
fields.append(QgsField('path', QVariant.String, '', 200))
|
self.fields.append(QgsField('path', QVariant.String, '', 200))
|
||||||
add_path_field = True
|
self.add_path_field = True
|
||||||
|
|
||||||
total = 100.0 / totalFeatureCount if totalFeatureCount else 1
|
total = 100.0 / totalFeatureCount if totalFeatureCount else 1
|
||||||
dest_crs = layers[0].crs()
|
self.dest_crs = layers[0].crs()
|
||||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
(self.sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
||||||
fields, layers[0].wkbType(), dest_crs)
|
self.fields, layers[0].wkbType(), self.dest_crs)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def processAlgorithm(self, context, feedback):
|
||||||
|
|
||||||
featureCount = 0
|
featureCount = 0
|
||||||
for layer in layers:
|
for layer in self.layers:
|
||||||
for feature in layer.getFeatures(QgsFeatureRequest().setDestinationCrs(dest_crs)):
|
for feature in layer.getFeatures(QgsFeatureRequest().setDestinationCrs(self.dest_crs)):
|
||||||
if feedback.isCanceled():
|
if feedback.isCanceled():
|
||||||
break
|
break
|
||||||
|
|
||||||
sattributes = feature.attributes()
|
sattributes = feature.attributes()
|
||||||
dattributes = []
|
dattributes = []
|
||||||
for dindex, dfield in enumerate(fields):
|
for dindex, dfield in enumerate(self.fields):
|
||||||
if add_layer_field and dfield.name() == 'layer':
|
if self.add_layer_field and dfield.name() == 'layer':
|
||||||
dattributes.append(layer.name())
|
dattributes.append(layer.name())
|
||||||
continue
|
continue
|
||||||
if add_path_field and dfield.name() == 'path':
|
if self.add_path_field and dfield.name() == 'path':
|
||||||
dattributes.append(layer.publicSource())
|
dattributes.append(layer.publicSource())
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -154,8 +164,10 @@ class Merge(QgisAlgorithm):
|
|||||||
dattributes.append(dattribute)
|
dattributes.append(dattribute)
|
||||||
|
|
||||||
feature.setAttributes(dattributes)
|
feature.setAttributes(dattributes)
|
||||||
sink.addFeature(feature, QgsFeatureSink.FastInsert)
|
self.sink.addFeature(feature, QgsFeatureSink.FastInsert)
|
||||||
featureCount += 1
|
featureCount += 1
|
||||||
feedback.setProgress(int(featureCount * total))
|
feedback.setProgress(int(featureCount * self.total))
|
||||||
|
return True
|
||||||
|
|
||||||
return {self.OUTPUT: dest_id}
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
|
return {self.OUTPUT: self.dest_id}
|
||||||
|
@ -53,20 +53,28 @@ class PostGISExecuteSQL(QgisAlgorithm):
|
|||||||
self.addParameter(db_param)
|
self.addParameter(db_param)
|
||||||
self.addParameter(QgsProcessingParameterString(self.SQL, self.tr('SQL query')))
|
self.addParameter(QgsProcessingParameterString(self.SQL, self.tr('SQL query')))
|
||||||
|
|
||||||
|
self.connection = None
|
||||||
|
self.sql = None
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'postgisexecutesql'
|
return 'postgisexecutesql'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('PostGIS execute SQL')
|
return self.tr('PostGIS execute SQL')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
connection = self.parameterAsString(parameters, self.DATABASE, context)
|
self.connection = self.parameterAsString(parameters, self.DATABASE, context)
|
||||||
db = postgis.GeoDB.from_name(connection)
|
self.sql = self.parameterAsString(parameters, self.SQL, context).replace('\n', ' ')
|
||||||
|
return True
|
||||||
|
|
||||||
sql = self.parameterAsString(parameters, self.SQL, context).replace('\n', ' ')
|
def processAlgorithm(self, context, feedback):
|
||||||
|
db = postgis.GeoDB.from_name(self.connection)
|
||||||
try:
|
try:
|
||||||
db._exec_sql_and_commit(str(sql))
|
db._exec_sql_and_commit(str(self.sql))
|
||||||
except postgis.DbError as e:
|
except postgis.DbError as e:
|
||||||
raise GeoAlgorithmExecutionException(
|
raise GeoAlgorithmExecutionException(
|
||||||
self.tr('Error executing SQL:\n{0}').format(str(e)))
|
self.tr('Error executing SQL:\n{0}').format(str(e)))
|
||||||
|
return True
|
||||||
|
|
||||||
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
return {}
|
return {}
|
||||||
|
@ -28,9 +28,7 @@ __revision__ = '$Format:%H$'
|
|||||||
|
|
||||||
import random
|
import random
|
||||||
|
|
||||||
from qgis.core import (QgsApplication,
|
from qgis.core import (QgsFeatureSink,
|
||||||
QgsFeatureSink,
|
|
||||||
QgsProcessingUtils,
|
|
||||||
QgsProcessingParameterFeatureSource,
|
QgsProcessingParameterFeatureSource,
|
||||||
QgsProcessingParameterEnum,
|
QgsProcessingParameterEnum,
|
||||||
QgsProcessingParameterNumber,
|
QgsProcessingParameterNumber,
|
||||||
@ -38,7 +36,6 @@ from qgis.core import (QgsApplication,
|
|||||||
QgsProcessingOutputVectorLayer)
|
QgsProcessingOutputVectorLayer)
|
||||||
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
||||||
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
|
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
|
||||||
from processing.core.outputs import OutputVector
|
|
||||||
|
|
||||||
|
|
||||||
class RandomExtract(QgisAlgorithm):
|
class RandomExtract(QgisAlgorithm):
|
||||||
@ -69,42 +66,54 @@ class RandomExtract(QgisAlgorithm):
|
|||||||
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Extracted (random)')))
|
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Extracted (random)')))
|
||||||
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Extracted (random)')))
|
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Extracted (random)')))
|
||||||
|
|
||||||
|
self.source = None
|
||||||
|
self.method = None
|
||||||
|
self.value = None
|
||||||
|
self.featureCount = None
|
||||||
|
self.sink = None
|
||||||
|
self.dest_id = None
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'randomextract'
|
return 'randomextract'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Random extract')
|
return self.tr('Random extract')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
source = self.parameterAsSource(parameters, self.INPUT, context)
|
self.source = self.parameterAsSource(parameters, self.INPUT, context)
|
||||||
method = self.parameterAsEnum(parameters, self.METHOD, context)
|
self.method = self.parameterAsEnum(parameters, self.METHOD, context)
|
||||||
|
self.value = self.parameterAsInt(parameters, self.NUMBER, context)
|
||||||
|
self.featureCount = self.source.featureCount()
|
||||||
|
|
||||||
features = source.getFeatures()
|
if self.method == 0:
|
||||||
featureCount = source.featureCount()
|
if self.value > self.featureCount:
|
||||||
value = self.parameterAsInt(parameters, self.NUMBER, context)
|
|
||||||
|
|
||||||
if method == 0:
|
|
||||||
if value > featureCount:
|
|
||||||
raise GeoAlgorithmExecutionException(
|
raise GeoAlgorithmExecutionException(
|
||||||
self.tr('Selected number is greater than feature count. '
|
self.tr('Selected number is greater than feature count. '
|
||||||
'Choose a lower value and try again.'))
|
'Choose a lower value and try again.'))
|
||||||
else:
|
else:
|
||||||
if value > 100:
|
if self.value > 100:
|
||||||
raise GeoAlgorithmExecutionException(
|
raise GeoAlgorithmExecutionException(
|
||||||
self.tr("Percentage can't be greater than 100. Set a "
|
self.tr("Percentage can't be greater than 100. Set a "
|
||||||
"different value and try again."))
|
"different value and try again."))
|
||||||
value = int(round(value / 100.0000, 4) * featureCount)
|
self.value = int(round(self.value / 100.0000, 4) * self.featureCount)
|
||||||
|
|
||||||
selran = random.sample(list(range(featureCount)), value)
|
(self.sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
||||||
|
self.source.fields(), self.source.wkbType(), self.source.sourceCrs())
|
||||||
|
|
||||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
return True
|
||||||
source.fields(), source.wkbType(), source.sourceCrs())
|
|
||||||
|
|
||||||
total = 100.0 / featureCount if featureCount else 1
|
def processAlgorithm(self, context, feedback):
|
||||||
|
selran = random.sample(list(range(self.featureCount)), self.value)
|
||||||
|
features = self.source.getFeatures()
|
||||||
|
|
||||||
|
total = 100.0 / self.featureCount if self.featureCount else 1
|
||||||
for i, feat in enumerate(features):
|
for i, feat in enumerate(features):
|
||||||
if feedback.isCanceled():
|
if feedback.isCanceled():
|
||||||
break
|
break
|
||||||
if i in selran:
|
if i in selran:
|
||||||
sink.addFeature(feat, QgsFeatureSink.FastInsert)
|
self.sink.addFeature(feat, QgsFeatureSink.FastInsert)
|
||||||
feedback.setProgress(int(i * total))
|
feedback.setProgress(int(i * total))
|
||||||
return {self.OUTPUT: dest_id}
|
return True
|
||||||
|
|
||||||
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
|
return {self.OUTPUT: self.dest_id}
|
||||||
|
@ -74,38 +74,46 @@ class RandomExtractWithinSubsets(QgisAlgorithm):
|
|||||||
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Extracted (random stratified)')))
|
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Extracted (random stratified)')))
|
||||||
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Extracted (random stratified)')))
|
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Extracted (random stratified)')))
|
||||||
|
|
||||||
|
self.source = None
|
||||||
|
self.method = None
|
||||||
|
self.field = None
|
||||||
|
self.value = None
|
||||||
|
self.sink = None
|
||||||
|
self.dest_id = None
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'randomextractwithinsubsets'
|
return 'randomextractwithinsubsets'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Random extract within subsets')
|
return self.tr('Random extract within subsets')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
source = self.parameterAsSource(parameters, self.INPUT, context)
|
self.source = self.parameterAsSource(parameters, self.INPUT, context)
|
||||||
method = self.parameterAsEnum(parameters, self.METHOD, context)
|
self.method = self.parameterAsEnum(parameters, self.METHOD, context)
|
||||||
|
|
||||||
field = self.parameterAsString(parameters, self.FIELD, context)
|
self.field = self.parameterAsString(parameters, self.FIELD, context)
|
||||||
|
self.value = self.parameterAsInt(parameters, self.NUMBER, context)
|
||||||
|
(self.sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
||||||
|
self.source.fields(), self.source.wkbType(), self.source.sourceCrs())
|
||||||
|
return True
|
||||||
|
|
||||||
index = source.fields().lookupField(field)
|
def processAlgorithm(self, context, feedback):
|
||||||
|
index = self.source.fields().lookupField(self.field)
|
||||||
|
|
||||||
features = source.getFeatures()
|
features = self.source.getFeatures()
|
||||||
featureCount = source.featureCount()
|
featureCount = self.source.featureCount()
|
||||||
unique = source.uniqueValues(index)
|
unique = self.source.uniqueValues(index)
|
||||||
value = self.parameterAsInt(parameters, self.NUMBER, context)
|
if self.method == 0:
|
||||||
if method == 0:
|
if self.value > featureCount:
|
||||||
if value > featureCount:
|
|
||||||
raise GeoAlgorithmExecutionException(
|
raise GeoAlgorithmExecutionException(
|
||||||
self.tr('Selected number is greater that feature count. '
|
self.tr('Selected number is greater that feature count. '
|
||||||
'Choose lesser value and try again.'))
|
'Choose lesser value and try again.'))
|
||||||
else:
|
else:
|
||||||
if value > 100:
|
if self.value > 100:
|
||||||
raise GeoAlgorithmExecutionException(
|
raise GeoAlgorithmExecutionException(
|
||||||
self.tr("Percentage can't be greater than 100. Set "
|
self.tr("Percentage can't be greater than 100. Set "
|
||||||
"correct value and try again."))
|
"correct value and try again."))
|
||||||
value = value / 100.0
|
self.value = self.value / 100.0
|
||||||
|
|
||||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
|
||||||
source.fields(), source.wkbType(), source.sourceCrs())
|
|
||||||
|
|
||||||
selran = []
|
selran = []
|
||||||
total = 100.0 / (featureCount * len(unique)) if featureCount else 1
|
total = 100.0 / (featureCount * len(unique)) if featureCount else 1
|
||||||
@ -119,13 +127,17 @@ class RandomExtractWithinSubsets(QgisAlgorithm):
|
|||||||
feedback.setProgress(int(i * total))
|
feedback.setProgress(int(i * total))
|
||||||
|
|
||||||
for subset in classes.values():
|
for subset in classes.values():
|
||||||
selValue = value if method != 1 else int(round(value * len(subset), 0))
|
selValue = self.value if self.method != 1 else int(round(self.value * len(subset), 0))
|
||||||
selran.extend(random.sample(subset, selValue))
|
selran.extend(random.sample(subset, selValue))
|
||||||
|
|
||||||
total = 100.0 / featureCount if featureCount else 1
|
total = 100.0 / featureCount if featureCount else 1
|
||||||
for (i, feat) in enumerate(selran):
|
for (i, feat) in enumerate(selran):
|
||||||
if feedback.isCanceled():
|
if feedback.isCanceled():
|
||||||
break
|
break
|
||||||
sink.addFeature(feat, QgsFeatureSink.FastInsert)
|
self.sink.addFeature(feat, QgsFeatureSink.FastInsert)
|
||||||
feedback.setProgress(int(i * total))
|
feedback.setProgress(int(i * total))
|
||||||
return {self.OUTPUT: dest_id}
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
|
return {self.OUTPUT: self.dest_id}
|
||||||
|
@ -81,55 +81,66 @@ class RegularPoints(QgisAlgorithm):
|
|||||||
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Regular points'), QgsProcessingParameterDefinition.TypeVectorPoint))
|
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Regular points'), QgsProcessingParameterDefinition.TypeVectorPoint))
|
||||||
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Regular points'), QgsProcessingParameterDefinition.TypeVectorPoint))
|
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Regular points'), QgsProcessingParameterDefinition.TypeVectorPoint))
|
||||||
|
|
||||||
|
self.extent = None
|
||||||
|
self.spacing = None
|
||||||
|
self.inset = None
|
||||||
|
self.randomize = None
|
||||||
|
self.isSpacing = None
|
||||||
|
self.fields = None
|
||||||
|
self.sink = None
|
||||||
|
self.dest_id = None
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'regularpoints'
|
return 'regularpoints'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Regular points')
|
return self.tr('Regular points')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
extent = self.parameterAsExtent(parameters, self.EXTENT, context)
|
self.extent = self.parameterAsExtent(parameters, self.EXTENT, context)
|
||||||
|
|
||||||
spacing = self.parameterAsDouble(parameters, self.SPACING, context)
|
self.spacing = self.parameterAsDouble(parameters, self.SPACING, context)
|
||||||
inset = self.parameterAsDouble(parameters, self.INSET, context)
|
self.inset = self.parameterAsDouble(parameters, self.INSET, context)
|
||||||
randomize = self.parameterAsBool(parameters, self.RANDOMIZE, context)
|
self.randomize = self.parameterAsBool(parameters, self.RANDOMIZE, context)
|
||||||
isSpacing = self.parameterAsBool(parameters, self.IS_SPACING, context)
|
self.isSpacing = self.parameterAsBool(parameters, self.IS_SPACING, context)
|
||||||
crs = self.parameterAsCrs(parameters, self.CRS, context)
|
crs = self.parameterAsCrs(parameters, self.CRS, context)
|
||||||
|
|
||||||
fields = QgsFields()
|
self.fields = QgsFields()
|
||||||
fields.append(QgsField('id', QVariant.Int, '', 10, 0))
|
self.fields.append(QgsField('id', QVariant.Int, '', 10, 0))
|
||||||
|
|
||||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
(self.sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
||||||
fields, QgsWkbTypes.Point, crs)
|
self.fields, QgsWkbTypes.Point, crs)
|
||||||
|
return True
|
||||||
|
|
||||||
if randomize:
|
def processAlgorithm(self, context, feedback):
|
||||||
|
if self.randomize:
|
||||||
seed()
|
seed()
|
||||||
|
|
||||||
area = extent.width() * extent.height()
|
area = self.extent.width() * self.extent.height()
|
||||||
if isSpacing:
|
if self.isSpacing:
|
||||||
pSpacing = spacing
|
pSpacing = self.spacing
|
||||||
else:
|
else:
|
||||||
pSpacing = sqrt(area / spacing)
|
pSpacing = sqrt(area / self.spacing)
|
||||||
|
|
||||||
f = QgsFeature()
|
f = QgsFeature()
|
||||||
f.initAttributes(1)
|
f.initAttributes(1)
|
||||||
f.setFields(fields)
|
f.setFields(self.fields)
|
||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
total = 100.0 / (area / pSpacing)
|
total = 100.0 / (area / pSpacing)
|
||||||
y = extent.yMaximum() - inset
|
y = self.extent.yMaximum() - self.inset
|
||||||
|
|
||||||
extent_geom = QgsGeometry.fromRect(extent)
|
extent_geom = QgsGeometry.fromRect(self.extent)
|
||||||
extent_engine = QgsGeometry.createGeometryEngine(extent_geom.geometry())
|
extent_engine = QgsGeometry.createGeometryEngine(extent_geom.geometry())
|
||||||
extent_engine.prepareGeometry()
|
extent_engine.prepareGeometry()
|
||||||
|
|
||||||
while y >= extent.yMinimum():
|
while y >= self.extent.yMinimum():
|
||||||
x = extent.xMinimum() + inset
|
x = self.extent.xMinimum() + self.inset
|
||||||
while x <= extent.xMaximum():
|
while x <= self.extent.xMaximum():
|
||||||
if feedback.isCanceled():
|
if feedback.isCanceled():
|
||||||
break
|
break
|
||||||
|
|
||||||
if randomize:
|
if self.randomize:
|
||||||
geom = QgsGeometry().fromPoint(QgsPointXY(
|
geom = QgsGeometry().fromPoint(QgsPointXY(
|
||||||
uniform(x - (pSpacing / 2.0), x + (pSpacing / 2.0)),
|
uniform(x - (pSpacing / 2.0), x + (pSpacing / 2.0)),
|
||||||
uniform(y - (pSpacing / 2.0), y + (pSpacing / 2.0))))
|
uniform(y - (pSpacing / 2.0), y + (pSpacing / 2.0))))
|
||||||
@ -139,10 +150,13 @@ class RegularPoints(QgisAlgorithm):
|
|||||||
if extent_engine.intersects(geom.geometry()):
|
if extent_engine.intersects(geom.geometry()):
|
||||||
f.setAttribute('id', count)
|
f.setAttribute('id', count)
|
||||||
f.setGeometry(geom)
|
f.setGeometry(geom)
|
||||||
sink.addFeature(f, QgsFeatureSink.FastInsert)
|
self.sink.addFeature(f, QgsFeatureSink.FastInsert)
|
||||||
x += pSpacing
|
x += pSpacing
|
||||||
count += 1
|
count += 1
|
||||||
feedback.setProgress(int(count * total))
|
feedback.setProgress(int(count * total))
|
||||||
y = y - pSpacing
|
y = y - pSpacing
|
||||||
|
|
||||||
return {self.OUTPUT: dest_id}
|
return True
|
||||||
|
|
||||||
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
|
return {self.OUTPUT: self.dest_id}
|
||||||
|
@ -26,12 +26,10 @@ __copyright__ = '(C) 2012, Victor Olaya'
|
|||||||
__revision__ = '$Format:%H$'
|
__revision__ = '$Format:%H$'
|
||||||
|
|
||||||
from qgis.core import (QgsFeatureSink,
|
from qgis.core import (QgsFeatureSink,
|
||||||
QgsProcessingUtils,
|
|
||||||
QgsProcessingParameterVectorLayer,
|
QgsProcessingParameterVectorLayer,
|
||||||
QgsProcessingParameterFeatureSink,
|
QgsProcessingParameterFeatureSink,
|
||||||
QgsProcessingOutputVectorLayer)
|
QgsProcessingOutputVectorLayer)
|
||||||
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
||||||
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
|
|
||||||
|
|
||||||
|
|
||||||
class SaveSelectedFeatures(QgisAlgorithm):
|
class SaveSelectedFeatures(QgisAlgorithm):
|
||||||
@ -49,27 +47,35 @@ class SaveSelectedFeatures(QgisAlgorithm):
|
|||||||
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Selection')))
|
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Selection')))
|
||||||
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr("Selection")))
|
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr("Selection")))
|
||||||
|
|
||||||
|
self.vectorLayer = None
|
||||||
|
self.sink = None
|
||||||
|
self.dest_id = None
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'saveselectedfeatures'
|
return 'saveselectedfeatures'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Save selected features')
|
return self.tr('Save selected features')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
vectorLayer = self.parameterAsVectorLayer(parameters, self.INPUT, context)
|
self.vectorLayer = self.parameterAsVectorLayer(parameters, self.INPUT, context)
|
||||||
|
|
||||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
(self.sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
||||||
vectorLayer.fields(), vectorLayer.wkbType(), vectorLayer.sourceCrs())
|
self.vectorLayer.fields(), self.vectorLayer.wkbType(), self.vectorLayer.sourceCrs())
|
||||||
|
return True
|
||||||
|
|
||||||
features = vectorLayer.getSelectedFeatures()
|
def processAlgorithm(self, context, feedback):
|
||||||
count = int(vectorLayer.selectedFeatureCount())
|
features = self.vectorLayer.getSelectedFeatures()
|
||||||
|
count = int(self.vectorLayer.selectedFeatureCount())
|
||||||
|
|
||||||
total = 100.0 / count if count else 1
|
total = 100.0 / count if count else 1
|
||||||
for current, feat in enumerate(features):
|
for current, feat in enumerate(features):
|
||||||
if feedback.isCanceled():
|
if feedback.isCanceled():
|
||||||
break
|
break
|
||||||
|
|
||||||
sink.addFeature(feat, QgsFeatureSink.FastInsert)
|
self.sink.addFeature(feat, QgsFeatureSink.FastInsert)
|
||||||
feedback.setProgress(int(current * total))
|
feedback.setProgress(int(current * total))
|
||||||
|
return True
|
||||||
|
|
||||||
return {self.OUTPUT: dest_id}
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
|
return {self.OUTPUT: self.dest_id}
|
||||||
|
@ -92,47 +92,60 @@ class SelectByAttribute(QgisAlgorithm):
|
|||||||
|
|
||||||
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Selected (attribute)')))
|
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Selected (attribute)')))
|
||||||
|
|
||||||
|
self.layer = None
|
||||||
|
self.fieldName = None
|
||||||
|
self.operator = None
|
||||||
|
self.value = None
|
||||||
|
self.input = None
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'selectbyattribute'
|
return 'selectbyattribute'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Select by attribute')
|
return self.tr('Select by attribute')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
layer = self.parameterAsVectorLayer(parameters, self.INPUT, context)
|
self.layer = self.parameterAsVectorLayer(parameters, self.INPUT, context)
|
||||||
|
|
||||||
fieldName = self.parameterAsString(parameters, self.FIELD, context)
|
self.fieldName = self.parameterAsString(parameters, self.FIELD, context)
|
||||||
operator = self.OPERATORS[self.parameterAsEnum(parameters, self.OPERATOR, context)]
|
self.operator = self.OPERATORS[self.parameterAsEnum(parameters, self.OPERATOR, context)]
|
||||||
value = self.parameterAsString(parameters, self.VALUE, context)
|
self.value = self.parameterAsString(parameters, self.VALUE, context)
|
||||||
|
|
||||||
fields = layer.fields()
|
self.input = parameters[self.INPUT]
|
||||||
|
return True
|
||||||
|
|
||||||
idx = layer.fields().lookupField(fieldName)
|
def processAlgorithm(self, context, feedback):
|
||||||
|
fields = self.layer.fields()
|
||||||
|
|
||||||
|
idx = self.layer.fields().lookupField(self.fieldName)
|
||||||
fieldType = fields[idx].type()
|
fieldType = fields[idx].type()
|
||||||
|
|
||||||
if fieldType != QVariant.String and operator in self.STRING_OPERATORS:
|
if fieldType != QVariant.String and self.operator in self.STRING_OPERATORS:
|
||||||
op = ''.join(['"%s", ' % o for o in self.STRING_OPERATORS])
|
op = ''.join(['"%s", ' % o for o in self.STRING_OPERATORS])
|
||||||
raise GeoAlgorithmExecutionException(
|
raise GeoAlgorithmExecutionException(
|
||||||
self.tr('Operators {0} can be used only with string fields.').format(op))
|
self.tr('Operators {0} can be used only with string fields.').format(op))
|
||||||
|
|
||||||
field_ref = QgsExpression.quotedColumnRef(fieldName)
|
field_ref = QgsExpression.quotedColumnRef(self.fieldName)
|
||||||
quoted_val = QgsExpression.quotedValue(value)
|
quoted_val = QgsExpression.quotedValue(self.value)
|
||||||
if operator == 'is null':
|
if self.operator == 'is null':
|
||||||
expression_string = '{} IS NULL'.format(field_ref)
|
expression_string = '{} IS NULL'.format(field_ref)
|
||||||
elif operator == 'is not null':
|
elif self.operator == 'is not null':
|
||||||
expression_string = '{} IS NOT NULL'.format(field_ref)
|
expression_string = '{} IS NOT NULL'.format(field_ref)
|
||||||
elif operator == 'begins with':
|
elif self.operator == 'begins with':
|
||||||
expression_string = """%s LIKE '%s%%'""" % (field_ref, value)
|
expression_string = """%s LIKE '%s%%'""" % (field_ref, self.value)
|
||||||
elif operator == 'contains':
|
elif self.operator == 'contains':
|
||||||
expression_string = """%s LIKE '%%%s%%'""" % (field_ref, value)
|
expression_string = """%s LIKE '%%%s%%'""" % (field_ref, self.value)
|
||||||
elif operator == 'does not contain':
|
elif self.operator == 'does not contain':
|
||||||
expression_string = """%s NOT LIKE '%%%s%%'""" % (field_ref, value)
|
expression_string = """%s NOT LIKE '%%%s%%'""" % (field_ref, self.value)
|
||||||
else:
|
else:
|
||||||
expression_string = '{} {} {}'.format(field_ref, operator, quoted_val)
|
expression_string = '{} {} {}'.format(field_ref, self.operator, quoted_val)
|
||||||
|
|
||||||
expression = QgsExpression(expression_string)
|
expression = QgsExpression(expression_string)
|
||||||
if expression.hasParserError():
|
if expression.hasParserError():
|
||||||
raise GeoAlgorithmExecutionException(expression.parserErrorString())
|
raise GeoAlgorithmExecutionException(expression.parserErrorString())
|
||||||
|
|
||||||
layer.selectByExpression(expression_string)
|
self.layer.selectByExpression(expression_string)
|
||||||
return {self.OUTPUT: parameters[self.INPUT]}
|
return True
|
||||||
|
|
||||||
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
|
return {self.OUTPUT: self.input}
|
||||||
|
@ -60,30 +60,42 @@ class SelectByExpression(QgisAlgorithm):
|
|||||||
|
|
||||||
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Selected (attribute)')))
|
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Selected (attribute)')))
|
||||||
|
|
||||||
|
self.layer = None
|
||||||
|
self.behavior = None
|
||||||
|
self.input = None
|
||||||
|
self.expression = None
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'selectbyexpression'
|
return 'selectbyexpression'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Select by expression')
|
return self.tr('Select by expression')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
layer = self.parameterAsVectorLayer(parameters, self.INPUT, context)
|
self.layer = self.parameterAsVectorLayer(parameters, self.INPUT, context)
|
||||||
|
|
||||||
method = self.parameterAsEnum(parameters, self.METHOD, context)
|
method = self.parameterAsEnum(parameters, self.METHOD, context)
|
||||||
|
|
||||||
if method == 0:
|
if method == 0:
|
||||||
behavior = QgsVectorLayer.SetSelection
|
self.behavior = QgsVectorLayer.SetSelection
|
||||||
elif method == 1:
|
elif method == 1:
|
||||||
behavior = QgsVectorLayer.AddToSelection
|
self.behavior = QgsVectorLayer.AddToSelection
|
||||||
elif method == 2:
|
elif method == 2:
|
||||||
behavior = QgsVectorLayer.RemoveFromSelection
|
self.behavior = QgsVectorLayer.RemoveFromSelection
|
||||||
elif method == 3:
|
elif method == 3:
|
||||||
behavior = QgsVectorLayer.IntersectSelection
|
self.behavior = QgsVectorLayer.IntersectSelection
|
||||||
|
|
||||||
expression = self.parameterAsString(parameters, self.EXPRESSION, context)
|
self.expression = self.parameterAsString(parameters, self.EXPRESSION, context)
|
||||||
qExp = QgsExpression(expression)
|
qExp = QgsExpression(self.expression)
|
||||||
if qExp.hasParserError():
|
if qExp.hasParserError():
|
||||||
raise GeoAlgorithmExecutionException(qExp.parserErrorString())
|
raise GeoAlgorithmExecutionException(qExp.parserErrorString())
|
||||||
|
|
||||||
layer.selectByExpression(expression, behavior)
|
self.input = parameters[self.INPUT]
|
||||||
return {self.OUTPUT: parameters[self.INPUT]}
|
return True
|
||||||
|
|
||||||
|
def processAlgorithm(self, context, feedback):
|
||||||
|
self.layer.selectByExpression(self.expression, self.behavior)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
|
return {self.OUTPUT: self.input}
|
||||||
|
@ -76,28 +76,37 @@ class SimplifyGeometries(QgisAlgorithm):
|
|||||||
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Simplified')))
|
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Simplified')))
|
||||||
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Simplified')))
|
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Simplified')))
|
||||||
|
|
||||||
|
self.source = None
|
||||||
|
self.tolerance = None
|
||||||
|
self.method = None
|
||||||
|
self.sink = None
|
||||||
|
self.dest_id = None
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'simplifygeometries'
|
return 'simplifygeometries'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Simplify geometries')
|
return self.tr('Simplify geometries')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
source = self.parameterAsSource(parameters, self.INPUT, context)
|
self.source = self.parameterAsSource(parameters, self.INPUT, context)
|
||||||
tolerance = self.parameterAsDouble(parameters, self.TOLERANCE, context)
|
self.tolerance = self.parameterAsDouble(parameters, self.TOLERANCE, context)
|
||||||
method = self.parameterAsEnum(parameters, self.METHOD, context)
|
self.method = self.parameterAsEnum(parameters, self.METHOD, context)
|
||||||
|
|
||||||
|
(self.sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
||||||
|
self.source.fields(), self.source.wkbType(), self.source.sourceCrs())
|
||||||
|
return True
|
||||||
|
|
||||||
|
def processAlgorithm(self, context, feedback):
|
||||||
pointsBefore = 0
|
pointsBefore = 0
|
||||||
pointsAfter = 0
|
pointsAfter = 0
|
||||||
|
|
||||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
features = self.source.getFeatures()
|
||||||
source.fields(), source.wkbType(), source.sourceCrs())
|
total = 100.0 / self.source.featureCount() if self.source.featureCount() else 0
|
||||||
|
|
||||||
features = source.getFeatures()
|
simplifier = None
|
||||||
total = 100.0 / source.featureCount() if source.featureCount() else 0
|
if self.method != 0:
|
||||||
|
simplifier = QgsMapToPixelSimplifier(QgsMapToPixelSimplifier.SimplifyGeometry, self.tolerance, self.method)
|
||||||
if method != 0:
|
|
||||||
simplifier = QgsMapToPixelSimplifier(QgsMapToPixelSimplifier.SimplifyGeometry, tolerance, method)
|
|
||||||
|
|
||||||
for current, input_feature in enumerate(features):
|
for current, input_feature in enumerate(features):
|
||||||
if feedback.isCanceled():
|
if feedback.isCanceled():
|
||||||
@ -107,18 +116,20 @@ class SimplifyGeometries(QgisAlgorithm):
|
|||||||
input_geometry = input_feature.geometry()
|
input_geometry = input_feature.geometry()
|
||||||
pointsBefore += input_geometry.geometry().nCoordinates()
|
pointsBefore += input_geometry.geometry().nCoordinates()
|
||||||
|
|
||||||
if method == 0: # distance
|
if self.method == 0: # distance
|
||||||
output_geometry = input_geometry.simplify(tolerance)
|
output_geometry = input_geometry.simplify(self.tolerance)
|
||||||
else:
|
else:
|
||||||
output_geometry = simplifier.simplify(input_geometry)
|
output_geometry = simplifier.simplify(input_geometry)
|
||||||
|
|
||||||
pointsAfter += output_geometry.geometry().nCoordinates()
|
pointsAfter += output_geometry.geometry().nCoordinates()
|
||||||
out_feature.setGeometry(output_geometry)
|
out_feature.setGeometry(output_geometry)
|
||||||
|
|
||||||
sink.addFeature(out_feature, QgsFeatureSink.FastInsert)
|
self.sink.addFeature(out_feature, QgsFeatureSink.FastInsert)
|
||||||
feedback.setProgress(int(current * total))
|
feedback.setProgress(int(current * total))
|
||||||
|
|
||||||
QgsMessageLog.logMessage(self.tr('Simplify: Input geometries have been simplified from {0} to {1} points').format(pointsBefore, pointsAfter),
|
QgsMessageLog.logMessage(self.tr('Simplify: Input geometries have been simplified from {0} to {1} points').format(pointsBefore, pointsAfter),
|
||||||
self.tr('Processing'), QgsMessageLog.INFO)
|
self.tr('Processing'), QgsMessageLog.INFO)
|
||||||
|
return True
|
||||||
|
|
||||||
return {self.OUTPUT: dest_id}
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
|
return {self.OUTPUT: self.dest_id}
|
||||||
|
@ -66,37 +66,48 @@ class Smooth(QgisAlgorithm):
|
|||||||
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Smoothed')))
|
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Smoothed')))
|
||||||
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Smoothed')))
|
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Smoothed')))
|
||||||
|
|
||||||
|
self.source = None
|
||||||
|
self.iterations = None
|
||||||
|
self.offset = None
|
||||||
|
self.max_angle = None
|
||||||
|
self.sink = None
|
||||||
|
self.dest_id = None
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'smoothgeometry'
|
return 'smoothgeometry'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Smooth geometry')
|
return self.tr('Smooth geometry')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
source = self.parameterAsSource(parameters, self.INPUT, context)
|
self.source = self.parameterAsSource(parameters, self.INPUT, context)
|
||||||
iterations = self.parameterAsInt(parameters, self.ITERATIONS, context)
|
self.iterations = self.parameterAsInt(parameters, self.ITERATIONS, context)
|
||||||
offset = self.parameterAsDouble(parameters, self.OFFSET, context)
|
self.offset = self.parameterAsDouble(parameters, self.OFFSET, context)
|
||||||
max_angle = self.parameterAsDouble(parameters, self.MAX_ANGLE, context)
|
self.max_angle = self.parameterAsDouble(parameters, self.MAX_ANGLE, context)
|
||||||
|
|
||||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
(self.sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
||||||
source.fields(), source.wkbType(), source.sourceCrs())
|
self.source.fields(), self.source.wkbType(), self.source.sourceCrs())
|
||||||
|
return True
|
||||||
|
|
||||||
features = source.getFeatures()
|
def processAlgorithm(self, context, feedback):
|
||||||
total = 100.0 / source.featureCount() if source.featureCount() else 0
|
features = self.source.getFeatures()
|
||||||
|
total = 100.0 / self.source.featureCount() if self.source.featureCount() else 0
|
||||||
|
|
||||||
for current, input_feature in enumerate(features):
|
for current, input_feature in enumerate(features):
|
||||||
if feedback.isCanceled():
|
if feedback.isCanceled():
|
||||||
break
|
break
|
||||||
output_feature = input_feature
|
output_feature = input_feature
|
||||||
if input_feature.geometry():
|
if input_feature.geometry():
|
||||||
output_geometry = input_feature.geometry().smooth(iterations, offset, -1, max_angle)
|
output_geometry = input_feature.geometry().smooth(self.iterations, self.offset, -1, self.max_angle)
|
||||||
if not output_geometry:
|
if not output_geometry:
|
||||||
raise GeoAlgorithmExecutionException(
|
raise GeoAlgorithmExecutionException(
|
||||||
self.tr('Error smoothing geometry'))
|
self.tr('Error smoothing geometry'))
|
||||||
|
|
||||||
output_feature.setGeometry(output_geometry)
|
output_feature.setGeometry(output_geometry)
|
||||||
|
|
||||||
sink.addFeature(output_feature, QgsFeatureSink.FastInsert)
|
self.sink.addFeature(output_feature, QgsFeatureSink.FastInsert)
|
||||||
feedback.setProgress(int(current * total))
|
feedback.setProgress(int(current * total))
|
||||||
|
return True
|
||||||
|
|
||||||
return {self.OUTPUT: dest_id}
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
|
return {self.OUTPUT: self.dest_id}
|
||||||
|
@ -49,26 +49,34 @@ class SpatialiteExecuteSQL(QgisAlgorithm):
|
|||||||
self.addParameter(QgsProcessingParameterVectorLayer(self.DATABASE, self.tr('File Database'), False, False))
|
self.addParameter(QgsProcessingParameterVectorLayer(self.DATABASE, self.tr('File Database'), False, False))
|
||||||
self.addParameter(QgsProcessingParameterString(self.SQL, self.tr('SQL query'), '', True))
|
self.addParameter(QgsProcessingParameterString(self.SQL, self.tr('SQL query'), '', True))
|
||||||
|
|
||||||
|
self.database = None
|
||||||
|
self.sql = None
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'spatialiteexecutesql'
|
return 'spatialiteexecutesql'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Spatialite execute SQL')
|
return self.tr('Spatialite execute SQL')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
database = self.parameterAsVectorLayer(parameters, self.DATABASE, context)
|
self.database = self.parameterAsVectorLayer(parameters, self.DATABASE, context)
|
||||||
databaseuri = database.dataProvider().dataSourceUri()
|
self.sql = self.parameterAsString(parameters, self.SQL, context).replace('\n', ' ')
|
||||||
|
return True
|
||||||
|
|
||||||
|
def processAlgorithm(self, context, feedback):
|
||||||
|
databaseuri = self.database.dataProvider().dataSourceUri()
|
||||||
uri = QgsDataSourceUri(databaseuri)
|
uri = QgsDataSourceUri(databaseuri)
|
||||||
if uri.database() is '':
|
if uri.database() is '':
|
||||||
if '|layerid' in databaseuri:
|
if '|layerid' in databaseuri:
|
||||||
databaseuri = databaseuri[:databaseuri.find('|layerid')]
|
databaseuri = databaseuri[:databaseuri.find('|layerid')]
|
||||||
uri = QgsDataSourceUri('dbname=\'%s\'' % (databaseuri))
|
uri = QgsDataSourceUri('dbname=\'%s\'' % (databaseuri))
|
||||||
db = spatialite.GeoDB(uri)
|
db = spatialite.GeoDB(uri)
|
||||||
sql = self.parameterAsString(parameters, self.SQL, context).replace('\n', ' ')
|
|
||||||
try:
|
try:
|
||||||
db._exec_sql_and_commit(str(sql))
|
db._exec_sql_and_commit(str(self.sql))
|
||||||
except spatialite.DbError as e:
|
except spatialite.DbError as e:
|
||||||
raise GeoAlgorithmExecutionException(
|
raise GeoAlgorithmExecutionException(
|
||||||
self.tr('Error executing SQL:\n{0}').format(str(e)))
|
self.tr('Error executing SQL:\n{0}').format(str(e)))
|
||||||
|
return True
|
||||||
|
|
||||||
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
return {}
|
return {}
|
||||||
|
@ -70,32 +70,39 @@ class SymmetricalDifference(QgisAlgorithm):
|
|||||||
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Symmetrical difference')))
|
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Symmetrical difference')))
|
||||||
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Symmetrical difference')))
|
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Symmetrical difference')))
|
||||||
|
|
||||||
|
self.sourceA = None
|
||||||
|
self.sourceB = None
|
||||||
|
self.sink = None
|
||||||
|
self.dest_id = None
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'symmetricaldifference'
|
return 'symmetricaldifference'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Symmetrical difference')
|
return self.tr('Symmetrical difference')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
sourceA = self.parameterAsSource(parameters, self.INPUT, context)
|
self.sourceA = self.parameterAsSource(parameters, self.INPUT, context)
|
||||||
sourceB = self.parameterAsSource(parameters, self.OVERLAY, context)
|
self.sourceB = self.parameterAsSource(parameters, self.OVERLAY, context)
|
||||||
|
|
||||||
geomType = QgsWkbTypes.multiType(sourceA.wkbType())
|
geomType = QgsWkbTypes.multiType(self.sourceA.wkbType())
|
||||||
fields = vector.combineFields(sourceA.fields(), sourceB.fields())
|
fields = vector.combineFields(self.sourceA.fields(), self.sourceB.fields())
|
||||||
|
|
||||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
(self.sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
||||||
fields, geomType, sourceA.sourceCrs())
|
fields, geomType, self.sourceA.sourceCrs())
|
||||||
|
return True
|
||||||
|
|
||||||
|
def processAlgorithm(self, context, feedback):
|
||||||
featB = QgsFeature()
|
featB = QgsFeature()
|
||||||
outFeat = QgsFeature()
|
outFeat = QgsFeature()
|
||||||
|
|
||||||
indexA = QgsSpatialIndex(sourceA)
|
indexA = QgsSpatialIndex(self.sourceA)
|
||||||
indexB = QgsSpatialIndex(sourceB.getFeatures(QgsFeatureRequest().setSubsetOfAttributes([]).setDestinationCrs(sourceA.sourceCrs())))
|
indexB = QgsSpatialIndex(self.sourceB.getFeatures(QgsFeatureRequest().setSubsetOfAttributes([]).setDestinationCrs(self.sourceA.sourceCrs())))
|
||||||
|
|
||||||
total = 100.0 / (sourceA.featureCount() * sourceB.featureCount()) if sourceA.featureCount() and sourceB.featureCount() else 1
|
total = 100.0 / (self.sourceA.featureCount() * self.sourceB.featureCount()) if self.sourceA.featureCount() and self.sourceB.featureCount() else 1
|
||||||
count = 0
|
count = 0
|
||||||
|
|
||||||
for featA in sourceA.getFeatures():
|
for featA in self.sourceA.getFeatures():
|
||||||
if feedback.isCanceled():
|
if feedback.isCanceled():
|
||||||
break
|
break
|
||||||
|
|
||||||
@ -104,8 +111,8 @@ class SymmetricalDifference(QgisAlgorithm):
|
|||||||
attrs = featA.attributes()
|
attrs = featA.attributes()
|
||||||
intersects = indexB.intersects(geom.boundingBox())
|
intersects = indexB.intersects(geom.boundingBox())
|
||||||
request = QgsFeatureRequest().setFilterFids(intersects).setSubsetOfAttributes([])
|
request = QgsFeatureRequest().setFilterFids(intersects).setSubsetOfAttributes([])
|
||||||
request.setDestinationCrs(sourceA.sourceCrs())
|
request.setDestinationCrs(self.sourceA.sourceCrs())
|
||||||
for featB in sourceB.getFeatures(request):
|
for featB in self.sourceB.getFeatures(request):
|
||||||
if feedback.isCanceled():
|
if feedback.isCanceled():
|
||||||
break
|
break
|
||||||
tmpGeom = featB.geometry()
|
tmpGeom = featB.geometry()
|
||||||
@ -115,7 +122,7 @@ class SymmetricalDifference(QgisAlgorithm):
|
|||||||
try:
|
try:
|
||||||
outFeat.setGeometry(diffGeom)
|
outFeat.setGeometry(diffGeom)
|
||||||
outFeat.setAttributes(attrs)
|
outFeat.setAttributes(attrs)
|
||||||
sink.addFeature(outFeat, QgsFeatureSink.FastInsert)
|
self.sink.addFeature(outFeat, QgsFeatureSink.FastInsert)
|
||||||
except:
|
except:
|
||||||
QgsMessageLog.logMessage(self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'),
|
QgsMessageLog.logMessage(self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'),
|
||||||
self.tr('Processing'), QgsMessageLog.WARNING)
|
self.tr('Processing'), QgsMessageLog.WARNING)
|
||||||
@ -124,9 +131,9 @@ class SymmetricalDifference(QgisAlgorithm):
|
|||||||
count += 1
|
count += 1
|
||||||
feedback.setProgress(int(count * total))
|
feedback.setProgress(int(count * total))
|
||||||
|
|
||||||
length = len(sourceA.fields())
|
length = len(self.sourceA.fields())
|
||||||
|
|
||||||
for featA in sourceB.getFeatures(QgsFeatureRequest().setDestinationCrs(sourceA.sourceCrs())):
|
for featA in self.sourceB.getFeatures(QgsFeatureRequest().setDestinationCrs(self.sourceA.sourceCrs())):
|
||||||
if feedback.isCanceled():
|
if feedback.isCanceled():
|
||||||
break
|
break
|
||||||
|
|
||||||
@ -136,7 +143,7 @@ class SymmetricalDifference(QgisAlgorithm):
|
|||||||
attrs = [NULL] * length + attrs
|
attrs = [NULL] * length + attrs
|
||||||
intersects = indexA.intersects(geom.boundingBox())
|
intersects = indexA.intersects(geom.boundingBox())
|
||||||
request = QgsFeatureRequest().setFilterFids(intersects).setSubsetOfAttributes([])
|
request = QgsFeatureRequest().setFilterFids(intersects).setSubsetOfAttributes([])
|
||||||
for featB in sourceA.getFeatures(request):
|
for featB in self.sourceA.getFeatures(request):
|
||||||
if feedback.isCanceled():
|
if feedback.isCanceled():
|
||||||
break
|
break
|
||||||
|
|
||||||
@ -147,7 +154,7 @@ class SymmetricalDifference(QgisAlgorithm):
|
|||||||
try:
|
try:
|
||||||
outFeat.setGeometry(diffGeom)
|
outFeat.setGeometry(diffGeom)
|
||||||
outFeat.setAttributes(attrs)
|
outFeat.setAttributes(attrs)
|
||||||
sink.addFeature(outFeat, QgsFeatureSink.FastInsert)
|
self.sink.addFeature(outFeat, QgsFeatureSink.FastInsert)
|
||||||
except:
|
except:
|
||||||
QgsMessageLog.logMessage(self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'),
|
QgsMessageLog.logMessage(self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'),
|
||||||
self.tr('Processing'), QgsMessageLog.WARNING)
|
self.tr('Processing'), QgsMessageLog.WARNING)
|
||||||
@ -155,5 +162,7 @@ class SymmetricalDifference(QgisAlgorithm):
|
|||||||
|
|
||||||
count += 1
|
count += 1
|
||||||
feedback.setProgress(int(count * total))
|
feedback.setProgress(int(count * total))
|
||||||
|
return True
|
||||||
|
|
||||||
return {self.OUTPUT: dest_id}
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
|
return {self.OUTPUT: self.dest_id}
|
||||||
|
@ -28,7 +28,6 @@ __revision__ = '$Format:%H$'
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from qgis.PyQt.QtGui import QIcon
|
|
||||||
from qgis.core import (QgsProcessingUtils,
|
from qgis.core import (QgsProcessingUtils,
|
||||||
QgsFeatureSink,
|
QgsFeatureSink,
|
||||||
QgsProcessingParameterFeatureSource,
|
QgsProcessingParameterFeatureSource,
|
||||||
@ -39,10 +38,6 @@ from qgis.core import (QgsProcessingUtils,
|
|||||||
QgsFeatureRequest)
|
QgsFeatureRequest)
|
||||||
|
|
||||||
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
||||||
from processing.core.parameters import ParameterVector
|
|
||||||
from processing.core.parameters import ParameterTableField
|
|
||||||
from processing.core.outputs import OutputDirectory
|
|
||||||
from processing.tools import vector
|
|
||||||
from processing.tools.system import mkdir
|
from processing.tools.system import mkdir
|
||||||
|
|
||||||
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
|
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
|
||||||
@ -71,42 +66,51 @@ class VectorSplit(QgisAlgorithm):
|
|||||||
|
|
||||||
self.addOutput(QgsProcessingOutputFolder(self.OUTPUT, self.tr('Output directory')))
|
self.addOutput(QgsProcessingOutputFolder(self.OUTPUT, self.tr('Output directory')))
|
||||||
|
|
||||||
|
self.source = None
|
||||||
|
self.fieldName = None
|
||||||
|
self.directory = None
|
||||||
|
self.uniqueValues = None
|
||||||
|
self.sinks = {}
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'splitvectorlayer'
|
return 'splitvectorlayer'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Split vector layer')
|
return self.tr('Split vector layer')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
source = self.parameterAsSource(parameters, self.INPUT, context)
|
self.source = self.parameterAsSource(parameters, self.INPUT, context)
|
||||||
fieldName = self.parameterAsString(parameters, self.FIELD, context)
|
self.fieldName = self.parameterAsString(parameters, self.FIELD, context)
|
||||||
directory = self.parameterAsString(parameters, self.OUTPUT, context)
|
self.directory = self.parameterAsString(parameters, self.OUTPUT, context)
|
||||||
|
mkdir(self.directory)
|
||||||
|
|
||||||
mkdir(directory)
|
fieldIndex = self.source.fields().lookupField(self.fieldName)
|
||||||
|
self.uniqueValues = self.source.uniqueValues(fieldIndex)
|
||||||
|
|
||||||
fieldIndex = source.fields().lookupField(fieldName)
|
baseName = os.path.join(self.directory, '{0}'.format(self.fieldName))
|
||||||
uniqueValues = source.uniqueValues(fieldIndex)
|
self.sinks = {}
|
||||||
baseName = os.path.join(directory, '{0}'.format(fieldName))
|
for current, i in enumerate(self.uniqueValues):
|
||||||
|
|
||||||
fields = source.fields()
|
|
||||||
crs = source.sourceCrs()
|
|
||||||
geomType = source.wkbType()
|
|
||||||
|
|
||||||
total = 100.0 / len(uniqueValues) if uniqueValues else 1
|
|
||||||
|
|
||||||
for current, i in enumerate(uniqueValues):
|
|
||||||
if feedback.isCanceled():
|
if feedback.isCanceled():
|
||||||
break
|
break
|
||||||
fName = u'{0}_{1}.shp'.format(baseName, str(i).strip())
|
fName = u'{0}_{1}.shp'.format(baseName, str(i).strip())
|
||||||
feedback.pushInfo(self.tr('Creating layer: {}').format(fName))
|
feedback.pushInfo(self.tr('Creating layer: {}').format(fName))
|
||||||
|
sink, dest = QgsProcessingUtils.createFeatureSink(fName, context, self.source.fields, self.source.wkbType(), self.source.sourceCrs())
|
||||||
|
self.sinks[i] = sink
|
||||||
|
return True
|
||||||
|
|
||||||
sink, dest = QgsProcessingUtils.createFeatureSink(fName, context, fields, geomType, crs)
|
def processAlgorithm(self, context, feedback):
|
||||||
|
total = 100.0 / len(self.uniqueValues) if self.uniqueValues else 1
|
||||||
|
for current, i in enumerate(self.uniqueValues):
|
||||||
|
if feedback.isCanceled():
|
||||||
|
break
|
||||||
|
|
||||||
filter = '{} = {}'.format(QgsExpression.quotedColumnRef(fieldName), QgsExpression.quotedValue(i))
|
sink = self.sinks[i]
|
||||||
|
|
||||||
|
filter = '{} = {}'.format(QgsExpression.quotedColumnRef(self.fieldName), QgsExpression.quotedValue(i))
|
||||||
req = QgsFeatureRequest().setFilterExpression(filter)
|
req = QgsFeatureRequest().setFilterExpression(filter)
|
||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
for f in source.getFeatures(req):
|
for f in self.source.getFeatures(req):
|
||||||
if feedback.isCanceled():
|
if feedback.isCanceled():
|
||||||
break
|
break
|
||||||
sink.addFeature(f, QgsFeatureSink.FastInsert)
|
sink.addFeature(f, QgsFeatureSink.FastInsert)
|
||||||
@ -115,5 +119,7 @@ class VectorSplit(QgisAlgorithm):
|
|||||||
del sink
|
del sink
|
||||||
|
|
||||||
feedback.setProgress(int(current * total))
|
feedback.setProgress(int(current * total))
|
||||||
|
return True
|
||||||
|
|
||||||
return {self.OUTPUT: directory}
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
|
return {self.OUTPUT: self.directory}
|
||||||
|
@ -94,30 +94,40 @@ class ZonalStatistics(QgisAlgorithm):
|
|||||||
self.tr('Zonal statistics'),
|
self.tr('Zonal statistics'),
|
||||||
QgsProcessingParameterDefinition.TypeVectorPolygon))
|
QgsProcessingParameterDefinition.TypeVectorPolygon))
|
||||||
|
|
||||||
|
self.bandNumber = None
|
||||||
|
self.columnPrefix = None
|
||||||
|
self.selectedStats = None
|
||||||
|
self.vectorLayer = None
|
||||||
|
self.rasterLayer = None
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'zonalstatistics'
|
return 'zonalstatistics'
|
||||||
|
|
||||||
def displayName(self):
|
def displayName(self):
|
||||||
return self.tr('Zonal Statistics')
|
return self.tr('Zonal Statistics')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
bandNumber = self.parameterAsInt(parameters, self.RASTER_BAND, context)
|
self.bandNumber = self.parameterAsInt(parameters, self.RASTER_BAND, context)
|
||||||
columnPrefix = self.parameterAsString(parameters, self.COLUMN_PREFIX, context)
|
self.columnPrefix = self.parameterAsString(parameters, self.COLUMN_PREFIX, context)
|
||||||
st = self.parameterAsEnums(parameters, self.STATISTICS, context)
|
st = self.parameterAsEnums(parameters, self.STATISTICS, context)
|
||||||
|
|
||||||
vectorLayer = self.parameterAsVectorLayer(parameters, self.INPUT_VECTOR, context)
|
|
||||||
rasterLayer = self.parameterAsRasterLayer(parameters, self.INPUT_RASTER, context)
|
|
||||||
|
|
||||||
keys = list(self.STATS.keys())
|
keys = list(self.STATS.keys())
|
||||||
selectedStats = 0
|
self.selectedStats = 0
|
||||||
for i in st:
|
for i in st:
|
||||||
selectedStats |= self.STATS[keys[i]]
|
self.selectedStats |= self.STATS[keys[i]]
|
||||||
|
|
||||||
zs = QgsZonalStatistics(vectorLayer,
|
self.vectorLayer = self.parameterAsVectorLayer(parameters, self.INPUT_VECTOR, context)
|
||||||
rasterLayer,
|
self.rasterLayer = self.parameterAsRasterLayer(parameters, self.INPUT_RASTER, context)
|
||||||
columnPrefix,
|
return True
|
||||||
bandNumber,
|
|
||||||
selectedStats)
|
def processAlgorithm(self, context, feedback):
|
||||||
|
zs = QgsZonalStatistics(self.vectorLayer,
|
||||||
|
self.rasterLayer,
|
||||||
|
self.columnPrefix,
|
||||||
|
self.bandNumber,
|
||||||
|
self.selectedStats)
|
||||||
zs.calculateStatistics(feedback)
|
zs.calculateStatistics(feedback)
|
||||||
|
return True
|
||||||
|
|
||||||
return {self.INPUT_VECTOR: vectorLayer}
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
|
return {self.INPUT_VECTOR: self.vectorLayer}
|
||||||
|
@ -75,6 +75,10 @@ class ScriptAlgorithm(QgsProcessingAlgorithm):
|
|||||||
if descriptionFile is not None:
|
if descriptionFile is not None:
|
||||||
self.defineCharacteristicsFromFile()
|
self.defineCharacteristicsFromFile()
|
||||||
|
|
||||||
|
self.ns = {}
|
||||||
|
self.cleaned_script = None
|
||||||
|
self.results = {}
|
||||||
|
|
||||||
def clone(self):
|
def clone(self):
|
||||||
return ScriptAlgorithm(self.descriptionFile)
|
return ScriptAlgorithm(self.descriptionFile)
|
||||||
|
|
||||||
@ -178,11 +182,7 @@ class ScriptAlgorithm(QgsProcessingAlgorithm):
|
|||||||
self.tr('Could not load script: {0}.\n'
|
self.tr('Could not load script: {0}.\n'
|
||||||
'Problem with line "{1}"', 'ScriptAlgorithm').format(self.descriptionFile or '', line))
|
'Problem with line "{1}"', 'ScriptAlgorithm').format(self.descriptionFile or '', line))
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def prepareAlgorithm(self, parameters, context, feedback):
|
||||||
ns = {}
|
|
||||||
|
|
||||||
ns['scriptDescriptionFile'] = self.descriptionFile
|
|
||||||
|
|
||||||
for param in self.parameterDefinitions():
|
for param in self.parameterDefinitions():
|
||||||
method = None
|
method = None
|
||||||
if param.type() == "boolean":
|
if param.type() == "boolean":
|
||||||
@ -224,20 +224,19 @@ class ScriptAlgorithm(QgsProcessingAlgorithm):
|
|||||||
method = self.parameterAsSource
|
method = self.parameterAsSource
|
||||||
|
|
||||||
if method:
|
if method:
|
||||||
ns[param.name()] = method(parameters, param.name(), context)
|
self.ns[param.name()] = method(parameters, param.name(), context)
|
||||||
|
|
||||||
|
self.ns['scriptDescriptionFile'] = self.descriptionFile
|
||||||
for out in self.outputDefinitions():
|
for out in self.outputDefinitions():
|
||||||
ns[out.name()] = None
|
self.ns[out.name()] = None
|
||||||
|
|
||||||
ns['self'] = self
|
self.ns['self'] = self
|
||||||
ns['parameters'] = parameters
|
self.ns['parameters'] = parameters
|
||||||
ns['feedback'] = feedback
|
|
||||||
ns['context'] = context
|
|
||||||
|
|
||||||
|
expression_context = self.createExpressionContext(parameters, context)
|
||||||
variables = re.findall('@[a-zA-Z0-9_]*', self.script)
|
variables = re.findall('@[a-zA-Z0-9_]*', self.script)
|
||||||
script = 'import processing\n'
|
script = 'import processing\n'
|
||||||
script += self.script
|
script += self.script
|
||||||
context = self.createExpressionContext(parameters, context)
|
|
||||||
for var in variables:
|
for var in variables:
|
||||||
varname = var[1:]
|
varname = var[1:]
|
||||||
if context.hasVariable(varname):
|
if context.hasVariable(varname):
|
||||||
@ -245,12 +244,22 @@ class ScriptAlgorithm(QgsProcessingAlgorithm):
|
|||||||
else:
|
else:
|
||||||
# messy - it's probably NOT a variable, and instead an email address or some other string containing '@'
|
# messy - it's probably NOT a variable, and instead an email address or some other string containing '@'
|
||||||
QgsMessageLog.logMessage(self.tr('Cannot find variable: {0}').format(varname), self.tr('Processing'), QgsMessageLog.WARNING)
|
QgsMessageLog.logMessage(self.tr('Cannot find variable: {0}').format(varname), self.tr('Processing'), QgsMessageLog.WARNING)
|
||||||
|
self.cleaned_script = script
|
||||||
|
|
||||||
exec((script), ns)
|
return True
|
||||||
results = {}
|
|
||||||
|
def processAlgorithm(self, context, feedback):
|
||||||
|
self.ns['feedback'] = feedback
|
||||||
|
self.ns['context'] = context
|
||||||
|
|
||||||
|
exec((self.cleaned_script), self.ns)
|
||||||
|
self.results = {}
|
||||||
for out in self.outputDefinitions():
|
for out in self.outputDefinitions():
|
||||||
results[out.name()] = ns[out.name()]
|
self.results[out.name()] = self.ns[out.name()]
|
||||||
return results
|
return True
|
||||||
|
|
||||||
|
def postProcessAlgorithm(self, context, feedback):
|
||||||
|
return self.results
|
||||||
|
|
||||||
def helpUrl(self):
|
def helpUrl(self):
|
||||||
if self.descriptionFile is None:
|
if self.descriptionFile is None:
|
||||||
|
@ -9,7 +9,7 @@ tests:
|
|||||||
type: vector # Param is a vector layer
|
type: vector # Param is a vector layer
|
||||||
name: polys.gml # file name
|
name: polys.gml # file name
|
||||||
results: # A map of results (only one here)
|
results: # A map of results (only one here)
|
||||||
OUTPUT_LAYER:
|
OUTPUT:
|
||||||
type: vector # Expected result is a vector layer
|
type: vector # Expected result is a vector layer
|
||||||
name: expected/polys_centroid.gml # The relative filepath from the processing testdata directory
|
name: expected/polys_centroid.gml # The relative filepath from the processing testdata directory
|
||||||
compare:
|
compare:
|
||||||
@ -735,7 +735,7 @@ tests:
|
|||||||
name: lines.gml
|
name: lines.gml
|
||||||
type: vector
|
type: vector
|
||||||
results:
|
results:
|
||||||
OUTPUT_LAYER:
|
OUTPUT:
|
||||||
name: expected/centroid_lines.gml
|
name: expected/centroid_lines.gml
|
||||||
type: vector
|
type: vector
|
||||||
compare:
|
compare:
|
||||||
@ -749,7 +749,7 @@ tests:
|
|||||||
name: multilines.gml
|
name: multilines.gml
|
||||||
type: vector
|
type: vector
|
||||||
results:
|
results:
|
||||||
OUTPUT_LAYER:
|
OUTPUT:
|
||||||
name: expected/centroid_multilines.gml
|
name: expected/centroid_multilines.gml
|
||||||
type: vector
|
type: vector
|
||||||
compare:
|
compare:
|
||||||
@ -763,7 +763,7 @@ tests:
|
|||||||
name: multipoints.gml
|
name: multipoints.gml
|
||||||
type: vector
|
type: vector
|
||||||
results:
|
results:
|
||||||
OUTPUT_LAYER:
|
OUTPUT:
|
||||||
name: expected/centroid_multipoint.gml
|
name: expected/centroid_multipoint.gml
|
||||||
type: vector
|
type: vector
|
||||||
compare:
|
compare:
|
||||||
@ -777,7 +777,7 @@ tests:
|
|||||||
name: multipolys.gml
|
name: multipolys.gml
|
||||||
type: vector
|
type: vector
|
||||||
results:
|
results:
|
||||||
OUTPUT_LAYER:
|
OUTPUT:
|
||||||
name: expected/centroid_multipolys.gml
|
name: expected/centroid_multipolys.gml
|
||||||
type: vector
|
type: vector
|
||||||
compare:
|
compare:
|
||||||
@ -791,7 +791,7 @@ tests:
|
|||||||
name: points.gml
|
name: points.gml
|
||||||
type: vector
|
type: vector
|
||||||
results:
|
results:
|
||||||
OUTPUT_LAYER:
|
OUTPUT:
|
||||||
name: expected/centroid_points.gml
|
name: expected/centroid_points.gml
|
||||||
type: vector
|
type: vector
|
||||||
compare:
|
compare:
|
||||||
@ -805,7 +805,7 @@ tests:
|
|||||||
name: polys.gml
|
name: polys.gml
|
||||||
type: vector
|
type: vector
|
||||||
results:
|
results:
|
||||||
OUTPUT_LAYER:
|
OUTPUT:
|
||||||
name: expected/centroid_polys.gml
|
name: expected/centroid_polys.gml
|
||||||
type: vector
|
type: vector
|
||||||
compare:
|
compare:
|
||||||
@ -1037,12 +1037,12 @@ tests:
|
|||||||
- algorithm: qgis:aspect
|
- algorithm: qgis:aspect
|
||||||
name: Aspect from QGIS analysis library
|
name: Aspect from QGIS analysis library
|
||||||
params:
|
params:
|
||||||
INPUT_LAYER:
|
INPUT:
|
||||||
name: dem.tif
|
name: dem.tif
|
||||||
type: raster
|
type: raster
|
||||||
Z_FACTOR: 1.0
|
Z_FACTOR: 1.0
|
||||||
results:
|
results:
|
||||||
OUTPUT_LAYER:
|
OUTPUT:
|
||||||
hash: 762865ee485a6736d188402aa10e6fd38a812a9e45a7dd2d4885a63a
|
hash: 762865ee485a6736d188402aa10e6fd38a812a9e45a7dd2d4885a63a
|
||||||
type: rasterhash
|
type: rasterhash
|
||||||
|
|
||||||
@ -1670,11 +1670,11 @@ tests:
|
|||||||
- algorithm: qgis:dropgeometries
|
- algorithm: qgis:dropgeometries
|
||||||
name: Drop geometries
|
name: Drop geometries
|
||||||
params:
|
params:
|
||||||
INPUT_LAYER:
|
INPUT:
|
||||||
name: polys.gml
|
name: polys.gml
|
||||||
type: vector
|
type: vector
|
||||||
results:
|
results:
|
||||||
OUTPUT_TABLE:
|
OUTPUT:
|
||||||
name: expected/dropped_geometry.csv
|
name: expected/dropped_geometry.csv
|
||||||
type: vector
|
type: vector
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ bool QgsCentroidAlgorithm::processAlgorithm( QgsProcessingContext &, QgsProcessi
|
|||||||
QVariantMap QgsCentroidAlgorithm::postProcessAlgorithm( QgsProcessingContext &, QgsProcessingFeedback * )
|
QVariantMap QgsCentroidAlgorithm::postProcessAlgorithm( QgsProcessingContext &, QgsProcessingFeedback * )
|
||||||
{
|
{
|
||||||
QVariantMap outputs;
|
QVariantMap outputs;
|
||||||
outputs.insert( QStringLiteral( "OUTPUT_LAYER" ), mSinkId );
|
outputs.insert( QStringLiteral( "OUTPUT" ), mSinkId );
|
||||||
return outputs;
|
return outputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4610,7 +4610,7 @@ void TestQgsProcessing::modelerAlgorithm()
|
|||||||
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> alg7c1outputs;
|
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> alg7c1outputs;
|
||||||
QgsProcessingModelAlgorithm::ModelOutput alg7c1out1( QStringLiteral( "my_output" ) );
|
QgsProcessingModelAlgorithm::ModelOutput alg7c1out1( QStringLiteral( "my_output" ) );
|
||||||
alg7c1out1.setChildId( "cx1" );
|
alg7c1out1.setChildId( "cx1" );
|
||||||
alg7c1out1.setChildOutputName( "OUTPUT_LAYER" );
|
alg7c1out1.setChildOutputName( "OUTPUT" );
|
||||||
alg7c1out1.setDescription( QStringLiteral( "my output" ) );
|
alg7c1out1.setDescription( QStringLiteral( "my output" ) );
|
||||||
alg7c1outputs.insert( QStringLiteral( "my_output" ), alg7c1out1 );
|
alg7c1outputs.insert( QStringLiteral( "my_output" ), alg7c1out1 );
|
||||||
alg7c1.setModelOutputs( alg7c1outputs );
|
alg7c1.setModelOutputs( alg7c1outputs );
|
||||||
@ -4630,7 +4630,7 @@ void TestQgsProcessing::modelerAlgorithm()
|
|||||||
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> alg7c2outputs;
|
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> alg7c2outputs;
|
||||||
QgsProcessingModelAlgorithm::ModelOutput alg7c2out1( QStringLiteral( "my_output2" ) );
|
QgsProcessingModelAlgorithm::ModelOutput alg7c2out1( QStringLiteral( "my_output2" ) );
|
||||||
alg7c2out1.setChildId( "cx2" );
|
alg7c2out1.setChildId( "cx2" );
|
||||||
alg7c2out1.setChildOutputName( "OUTPUT_LAYER" );
|
alg7c2out1.setChildOutputName( "OUTPUT" );
|
||||||
alg7c2out1.setDescription( QStringLiteral( "my output2" ) );
|
alg7c2out1.setDescription( QStringLiteral( "my output2" ) );
|
||||||
alg7c2outputs.insert( QStringLiteral( "my_output2" ), alg7c2out1 );
|
alg7c2outputs.insert( QStringLiteral( "my_output2" ), alg7c2out1 );
|
||||||
alg7c2.setModelOutputs( alg7c2outputs );
|
alg7c2.setModelOutputs( alg7c2outputs );
|
||||||
@ -4700,7 +4700,7 @@ void TestQgsProcessing::modelExecution()
|
|||||||
alg2c1.addParameterSources( "DISSOLVE", QgsProcessingModelAlgorithm::ChildParameterSources() << QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( false ) );
|
alg2c1.addParameterSources( "DISSOLVE", QgsProcessingModelAlgorithm::ChildParameterSources() << QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( false ) );
|
||||||
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> outputs1;
|
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> outputs1;
|
||||||
QgsProcessingModelAlgorithm::ModelOutput out1( "MODEL_OUT_LAYER" );
|
QgsProcessingModelAlgorithm::ModelOutput out1( "MODEL_OUT_LAYER" );
|
||||||
out1.setChildOutputName( "OUTPUT_LAYER" );
|
out1.setChildOutputName( "OUTPUT" );
|
||||||
outputs1.insert( QStringLiteral( "MODEL_OUT_LAYER" ), out1 );
|
outputs1.insert( QStringLiteral( "MODEL_OUT_LAYER" ), out1 );
|
||||||
alg2c1.setModelOutputs( outputs1 );
|
alg2c1.setModelOutputs( outputs1 );
|
||||||
model2.addChildAlgorithm( alg2c1 );
|
model2.addChildAlgorithm( alg2c1 );
|
||||||
@ -4720,7 +4720,7 @@ void TestQgsProcessing::modelExecution()
|
|||||||
QCOMPARE( params.value( "END_CAP_STYLE" ).toInt(), 1 );
|
QCOMPARE( params.value( "END_CAP_STYLE" ).toInt(), 1 );
|
||||||
QCOMPARE( params.value( "JOIN_STYLE" ).toInt(), 2 );
|
QCOMPARE( params.value( "JOIN_STYLE" ).toInt(), 2 );
|
||||||
QCOMPARE( params.value( "INPUT" ).toString(), QStringLiteral( "my_layer_id" ) );
|
QCOMPARE( params.value( "INPUT" ).toString(), QStringLiteral( "my_layer_id" ) );
|
||||||
QCOMPARE( params.value( "OUTPUT_LAYER" ).toString(), QStringLiteral( "dest.shp" ) );
|
QCOMPARE( params.value( "OUTPUT" ).toString(), QStringLiteral( "dest.shp" ) );
|
||||||
QCOMPARE( params.count(), 7 );
|
QCOMPARE( params.count(), 7 );
|
||||||
|
|
||||||
QVariantMap results;
|
QVariantMap results;
|
||||||
@ -4735,7 +4735,7 @@ void TestQgsProcessing::modelExecution()
|
|||||||
model2.addChildAlgorithm( alg2c2 );
|
model2.addChildAlgorithm( alg2c2 );
|
||||||
params = model2.parametersForChildAlgorithm( model2.childAlgorithm( "cx2" ), modelInputs, childResults );
|
params = model2.parametersForChildAlgorithm( model2.childAlgorithm( "cx2" ), modelInputs, childResults );
|
||||||
QCOMPARE( params.value( "INPUT" ).toString(), QStringLiteral( "dest.shp" ) );
|
QCOMPARE( params.value( "INPUT" ).toString(), QStringLiteral( "dest.shp" ) );
|
||||||
QCOMPARE( params.value( "OUTPUT_LAYER" ).toString(), QStringLiteral( "memory:" ) );
|
QCOMPARE( params.value( "OUTPUT" ).toString(), QStringLiteral( "memory:" ) );
|
||||||
QCOMPARE( params.count(), 2 );
|
QCOMPARE( params.count(), 2 );
|
||||||
|
|
||||||
// a child with an optional output
|
// a child with an optional output
|
||||||
@ -4770,8 +4770,8 @@ void TestQgsProcessing::modelExecution()
|
|||||||
"##my_out=output outputVector\n"
|
"##my_out=output outputVector\n"
|
||||||
"results={}\n"
|
"results={}\n"
|
||||||
"outputs['cx1']=processing.run('native:buffer', {'DISSOLVE':false,'DISTANCE':parameters['DIST'],'END_CAP_STYLE':1,'INPUT':parameters['SOURCE_LAYER'],'JOIN_STYLE':2,'SEGMENTS':16}, context=context, feedback=feedback)\n"
|
"outputs['cx1']=processing.run('native:buffer', {'DISSOLVE':false,'DISTANCE':parameters['DIST'],'END_CAP_STYLE':1,'INPUT':parameters['SOURCE_LAYER'],'JOIN_STYLE':2,'SEGMENTS':16}, context=context, feedback=feedback)\n"
|
||||||
"results['MODEL_OUT_LAYER']=outputs['cx1']['OUTPUT_LAYER']\n"
|
"results['MODEL_OUT_LAYER']=outputs['cx1']['OUTPUT']\n"
|
||||||
"outputs['cx2']=processing.run('native:centroids', {'INPUT':outputs['cx1']['OUTPUT_LAYER']}, context=context, feedback=feedback)\n"
|
"outputs['cx2']=processing.run('native:centroids', {'INPUT':outputs['cx1']['OUTPUT']}, context=context, feedback=feedback)\n"
|
||||||
"outputs['cx3']=processing.run('native:extractbyexpression', {'EXPRESSION':true,'INPUT':outputs['cx1']['OUTPUT_LAYER'],'OUTPUT':parameters['MY_OUT']}, context=context, feedback=feedback)\n"
|
"outputs['cx3']=processing.run('native:extractbyexpression', {'EXPRESSION':true,'INPUT':outputs['cx1']['OUTPUT_LAYER'],'OUTPUT':parameters['MY_OUT']}, context=context, feedback=feedback)\n"
|
||||||
"results['MY_OUT']=outputs['cx3']['OUTPUT']\n"
|
"results['MY_OUT']=outputs['cx3']['OUTPUT']\n"
|
||||||
"return results" ).split( '\n' );
|
"return results" ).split( '\n' );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user