I've created a processing script in QGIS 3.10, but can't seem to achieve the last step of styling the processed layer. My script follows the new easy processing script format that have come back since version 3.6.
I've referenced QGIS 3.4, how to add .qml style to sink in processing, but my script doesn't seem to run the postProcessAlgorithm bit below.
from math import *
from PyQt5.QtCore import QCoreApplication, QVariant
from qgis.processing import alg
from qgis.core import (QgsProcessing,
QgsFeatureSink,
QgsFeature,
QgsVectorLayer,
QgsGeometry,
QgsPointXY,
QgsField,
QgsFields,
QgsWkbTypes,
QgsProject,
QgsProcessingException,
QgsProcessingAlgorithm,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterFeatureSink,
QgsProcessingParameterField,
QgsVectorFileWriter
)
from qgis.utils import iface
import processing
@alg(name="distance_buffer", label=alg.tr("Distance Buffer"), group="base", group_label=alg.tr("base"))
@alg.input(type=alg.SOURCE, name="INPUT", label="Input layer")
@alg.input(type=alg.SINK, name="OUTPUT", label="Distance Buffers")
@alg.input(type=alg.FILE, name='STYLEFILE', label='Style file', default='C:/Desktop/Buffer.qml')
def processAlgorithm(instance, parameters, context, feedback, inputs):
"""
Create accurate distance buffers with reprojection.
"""
source = instance.parameterAsSource(parameters, "INPUT", context)
if source is None:
raise QgsProcessingException(instance.invalidSourceError(parameters, "INPUT"))
fields = QgsFields()
fields.append(QgsField("Distance", QVariant.Int))
fields.append(QgsField("Label", QVariant.String))
(sink, dest_id) = instance.parameterAsSink(parameters, "OUTPUT", context,
fields,
QgsWkbTypes.Polygon,
source.sourceCrs()
)
if sink is None:
raise QgsProcessingException(instance.invalidSinkError(parameters, "OUTPUT"))
total = 100.0 / source.featureCount() if source.featureCount() else 0
selection = source.getFeatures()
for current, feature in enumerate(selection):
if feedback.isCanceled():
break
for select in selection:
geom = select.geometry()
start_x = geom.asPoint().x()
start_y = geom.asPoint().y()
sides = 64
radius = 6378137.0 # meters
distance = [250, 500, 1000, 2000, 3000, 4000, 5000, 10000, 15000, 20000, 25000, 30000, 40000, 50000]
feedback.pushInfo('Creating layer and adding fields.')
# Create new layer.
vl = QgsVectorLayer("Polygon", "Distance Buffers", "memory")
# Add fields.
pr = vl.dataProvider()
pr.addAttributes(fields)
vl.updateFields()
for i in range(len(distance)):
feedback.pushInfo('Creating feature.')
points = []
dist = distance[i]
degrees = 0
while degrees <= 360:
degrees = degrees + 360 / sides
start_lon = start_x * pi / 180
start_lat = start_y * pi / 180
bearing = degrees * pi / 180
end_lat = asin((sin(start_lat) * cos(dist / radius)) + (cos(start_lat) * sin(dist / radius) * cos(bearing)))
end_lon = start_lon + atan2(sin(bearing) * sin(dist / radius) * cos(start_lat),
cos(dist / radius) - (sin(start_lat) * sin(end_lat)))
points.append(QgsPointXY(end_lon * 180 / pi, end_lat * 180 / pi))
feat_name = str(distance[i])
if distance[i] < 1000:
label = str(distance[i]) + "m"
else:
label = str(distance[i]/1000) + "km"
feedback.pushInfo('Adding feature to layer.')
# Add calculated features.
feat = QgsFeature()
geometry = QgsGeometry.fromPolygonXY([points])
feat.setGeometry(geometry)
feat.setAttributes([feat_name,label])
sink.addFeature(feat, QgsFeatureSink.FastInsert)
feedback.setProgress(int(current * total))
return {"OUTPUT": dest_id}
def postProcessAlgorithm(self, context, feedback):
style = instance.parameterAsString(parameters, "STYLEFILE", context)
processed_layer = QgsProcessingUtils.mapLayerFromString(dest_id, context)
processed_layer.loadNamedStyle(style)
processed_layer.triggerRepaint()
feedback.pushInfo('Loaded buffer styling.')
return {"OUTPUT": dest_id}
Has this changed since version 3.6?
self.dest_id
instead ofdest_id
andself.
instead ofinstance.