<div dir="ltr"><div>Hi All,</div><div><br></div><div>Can someone offer me some guidance on the new scripting process in QGIS 3x? <br></div><div><br></div><div>If I take the create script from template option and make some very minor changes (below), why am I not writing a buffer? The script will execute with no errors, is this line
buffered_layer = processing.run("native:buffer",...... even being run?<br></div><div><br></div><div>The lines I have changed from the template are show with ###</div><div><br></div><div>I am not clear on how
QgsFeatureSinkis working, perhaps that is why I am not getting the buffered layer? Normally in a script I could try printing variables I cannot see where these are printed either when I tested.<br></div><div><br></div><div>Ultimately I'd like to expand the script, but first I am hoping to just be able to call a simple buffer. <br></div><div><br></div><div>Thanks in advance for any help<br></div><div><br></div><div>Kind Regards</div><div>Andrew<br></div><div><br></div><div><br></div><div><br>"""<br>***************************************************************************<br>* *<br>* This program is free software; you can redistribute it and/or modify *<br>* it under the terms of the GNU General Public License as published by *<br>* the Free Software Foundation; either version 2 of the License, or *<br>* (at your option) any later version. *<br>* *<br>***************************************************************************<br>"""<br><br>from PyQt5.QtCore import QCoreApplication<br>from qgis.core import (QgsProcessing,<br> QgsFeatureSink,<br> QgsProcessingException,<br> QgsProcessingAlgorithm,<br> QgsProcessingParameterFeatureSource,<br> QgsProcessingParameterFeatureSink)<br>import processing<br><br><br>class ExampleProcessingAlgorithm(QgsProcessingAlgorithm):<br> """<br> This is an example algorithm that takes a vector layer and<br> creates a new identical one.<br><br> It is meant to be used as an example of how to create your own<br> algorithms and explain methods and variables used to do it. An<br> algorithm like this will be available in all elements, and there<br> is not need for additional work.<br><br> All Processing algorithms should extend the QgsProcessingAlgorithm<br> class.<br> """<br><br> # Constants used to refer to parameters and outputs. They will be<br> # used when calling the algorithm from another algorithm, or when<br> # calling from the QGIS console.<br><br> INPUT = 'INPUT'<br> OUTPUT = 'OUTPUT'<br><br> def tr(self, string):<br> """<br> Returns a translatable string with the <a href="http://self.tr">self.tr</a>() function.<br> """<br> return QCoreApplication.translate('Processing', string)<br><br> def createInstance(self):<br> return ExampleProcessingAlgorithm()<br><br> def name(self):<br> """<br> Returns the algorithm name, used for identifying the algorithm. This<br> string should be fixed for the algorithm, and must not be localised.<br> The name should be unique within each provider. Names should contain<br> lowercase alphanumeric characters only and no spaces or other<br> formatting characters.<br> """<br> return 'myscript'<br><br> def displayName(self):<br> """<br> Returns the translated algorithm name, which should be used for any<br> user-visible display of the algorithm name.<br> """<br> return <a href="http://self.tr">self.tr</a>('My Script')<br><br> def group(self):<br> """<br> Returns the name of the group this algorithm belongs to. This string<br> should be localised.<br> """<br> return <a href="http://self.tr">self.tr</a>('Example scripts')<br><br> def groupId(self):<br> """<br> Returns the unique ID of the group this algorithm belongs to. This<br> string should be fixed for the algorithm, and must not be localised.<br> The group id should be unique within each provider. Group id should<br> contain lowercase alphanumeric characters only and no spaces or other<br> formatting characters.<br> """<br> return 'examplescripts'<br><br> def shortHelpString(self):<br> """<br> Returns a localised short helper string for the algorithm. This string<br> should provide a basic description about what the algorithm does and the<br> parameters and outputs associated with it..<br> """<br> return <a href="http://self.tr">self.tr</a>("Example algorithm short description")<br><br> def initAlgorithm(self, config=None):<br> """<br> Here we define the inputs and output of the algorithm, along<br> with some other properties.<br> """<br><br> # We add the input vector features source. It can have any kind of<br> # geometry.<br> self.addParameter(<br> QgsProcessingParameterFeatureSource(<br> self.INPUT,<br> <a href="http://self.tr">self.tr</a>('Input layer'),<br> [QgsProcessing.TypeVectorAnyGeometry]<br> )<br> )<br><br> # We add a feature sink in which to store our processed features (this<br> # usually takes the form of a newly created vector layer when the<br> # algorithm is run in QGIS).<br> self.addParameter(<br> QgsProcessingParameterFeatureSink(<br> self.OUTPUT,<br> <a href="http://self.tr">self.tr</a>('Output layer')<br> )<br> )<br><br> def processAlgorithm(self, parameters, context, feedback):<br> """<br> Here is where the processing itself takes place.<br> """<br><br> # Retrieve the feature source and sink. The 'dest_id' variable is used<br> # to uniquely identify the feature sink, and must be included in the<br> # dictionary returned by the processAlgorithm function.<br> source = self.parameterAsSource(<br> parameters,<br> self.INPUT,<br> context<br> )<br><br> # If source was not found, throw an exception to indicate that the algorithm<br> # encountered a fatal error. The exception text can be any string, but in this<br> # case we use the pre-built invalidSourceError method to return a standard<br> # helper text for when a source cannot be evaluated<br> if source is None:<br> raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))<br><br> (sink, dest_id) = self.parameterAsSink(<br> parameters,<br> self.OUTPUT,<br> context,<br> source.fields(),<br> source.wkbType(),<br> source.sourceCrs()<br> )<br><br> # If sink was not created, throw an exception to indicate that the algorithm<br> # encountered a fatal error. The exception text can be any string, but in this<br> # case we use the pre-built invalidSinkError method to return a standard<br> # helper text for when a sink cannot be evaluated<br> if sink is None:<br> raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT))<br><br> # Compute the number of steps to display within the progress bar and<br> # get features from source<br> total = 100.0 / source.featureCount() if source.featureCount() else 0<br> features = source.getFeatures()<br><br> for current, feature in enumerate(features):<br> # Stop the algorithm if cancel button has been clicked<br> if feedback.isCanceled():<br> break<br><br> # Add a feature in the sink<br> sink.addFeature(feature, QgsFeatureSink.FastInsert)<br><br> # Update the progress bar<br> feedback.setProgress(int(current * total))<br><br> # To run another Processing algorithm as part of this algorithm, you can use<br> # processing.run(...). Make sure you pass the current context and feedback<br> # to processing.run to ensure that all temporary layer outputs are available<br> # to the executed algorithm, and that the executed algorithm can send feedback<br> # reports to the user (and correctly handle cancelation and progress reports!)<br> <br> ### removed if False:<br> <br> buffered_layer = processing.run("native:buffer", { ### removed PARAM<br> 'INPUT': dest_id,<br> 'DISTANCE': 1.5,<br> 'SEGMENTS': 5,<br> 'END_CAP_STYLE': 0,<br> 'JOIN_STYLE': 0,<br> 'MITER_LIMIT': 2,<br> 'DISSOLVE': False,<br> 'OUTPUT': 'memory:'<br> }, context=context, feedback=feedback)['OUTPUT']<br><br> # Return the results of the algorithm. In this case our only result is<br> # the feature sink which contains the processed features, but some<br> # algorithms may return multiple feature sinks, calculated numeric<br> # statistics, etc. These should all be included in the returned<br> # dictionary, with keys matching the feature corresponding parameter<br> # or output names.<br> return {self.OUTPUT: buffered_layer} ### changed output name<br></div></div>