I created a QGIS Plugin which is available in the processing toolbar. I want to give users the possibility to either create a new temporary layer (or save in a new file) or use the "edit feature in place" possibility of QGIS processing:
Button to edit feature in place
I couldn't find a solution in this tutorial: https://www.qgistutorials.com/en/docs/3/processing_python_plugin.html When I activate the "edit feature in place", my self-made processing tool is not available.
Alternatively I would have to only give the possibility to edit features in an existing layer as in this answer: https://gis.stackexchange.com/a/412130/193285
1 Answer 1
To allow your custom algorithm to edit features in place and be available in the toolbox when the Edit Features In-Place icon is toggled on, you need to override two methods in your QgsProcessingAlgorithm
sub-class.
The first is the flags()
method where you need to return the SupportsInPlaceEdits
ProcessingAlgorithmFlag
.
E.g.
def flags(self):
return Qgis.ProcessingAlgorithmFlag.SupportsInPlaceEdits
Note that prior to QGIS 3.36, this would be:
def flags(self):
return QgsProcessingAlgorithm.FlagSupportsInPlaceEdits
Secondly, you need to also override the supportInPlaceEdit()
method. the QgsMapLayer
argument which gets passed to this method is the active layer (on which the algorithm would be executed in place). So this method needs to return a Boolean value based on whether the active layer can support the algorithm's operation. For example, if your algorithm produces geometries of a different type than the input layer, it can not be run in place. e.g. a buffer operation cannot edit features in place with a point or line input layer.
So, in this method, you need to take care to do whatever checks are necessary and only return True
if the operations implemented in your algorithm can be successfully run on the features of the input layer e.g.
def supportInPlaceEdit(self, lyr):
return lyr.wkbType() == Qgis.WkbType.Polygon or lyr.wkbType() == Qgis.WkbType.MultiPolygon
Or for versions prior to 3.30:
def supportInPlaceEdit(self, lyr):
return lyr.wkbType() == QgsWkbTypes.Polygon or lyr.wkbType() == QgsWkbTypes.MultiPolygon
Here is a complete, basic example script:
from qgis.PyQt.QtCore import QCoreApplication, QVariant
from qgis.core import (Qgis, QgsProcessing, QgsProcessingAlgorithm,
QgsProcessingParameterFeatureSource, QgsProcessingParameterDistance,
QgsProcessingParameterFeatureSink, QgsFeature, QgsWkbTypes,
QgsFeatureSink)
class ExBufferInPlace(QgsProcessingAlgorithm):
INPUT = 'INPUT'
DISTANCE = 'DISTANCE'
OUTPUT = 'OUTPUT'
def __init__(self):
super().__init__()
def name(self):
return "bufferpoly"
def tr(self, text):
return QCoreApplication.translate("bufferpoly", text)
def displayName(self):
return self.tr("In place example")
def group(self):
return self.tr("Examples")
def groupId(self):
return "examples"
def shortHelpString(self):
return self.tr("Example supporting edit in place")
def helpUrl(self):
return "https://qgis.org"
def createInstance(self):
return type(self)()
def flags(self):
return QgsProcessingAlgorithm.FlagSupportsInPlaceEdits
def initAlgorithm(self, config=None):
self.addParameter(QgsProcessingParameterFeatureSource(
self.INPUT,
self.tr("Input layer"),
[QgsProcessing.TypeVectorAnyGeometry]))
self.addParameter(QgsProcessingParameterDistance(
self.DISTANCE,
self.tr('Distance'),
parentParameterName=self.INPUT))
self.addParameter(QgsProcessingParameterFeatureSink(
self.OUTPUT,
self.tr("Output layer"),
QgsProcessing.TypeVectorAnyGeometry))
def supportInPlaceEdit(self, lyr):
return lyr.wkbType() == QgsWkbTypes.Polygon or lyr.wkbType() == QgsWkbTypes.MultiPolygon
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
dist_value = self.parameterAsDouble(parameters, self.DISTANCE, context)
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
source.fields(), QgsWkbTypes.Polygon, source.sourceCrs())
for f in source.getFeatures():
g = f.geometry().buffer(dist_value, 25)
out_feat = QgsFeature()
out_feat.setGeometry(g)
out_feat.setAttributes(f.attributes())
sink.addFeature(out_feat, QgsFeatureSink.FastInsert)
return {self.OUTPUT: dest_id}
The resulting behaviour is shown below- with the edit in place filter toggled on and a polygon layer selected, my example algorithm is available:
If I switch the active layer to a point layer, my algorithm is no longer available:
Explore related questions
See similar questions with these tags.