In the workshop material "QGIS Automation using Actions", the first example "1.1 Extract a Feature from a Layer" demonstrates how one can extract any country polygon by clicking on it. I would like to alter the code in that way, that a buffer of 200 km around the country I have clicked on is created and added to the map as temporary layer.
So, I reprojected the World map layer (Admin0 - Country boundaries dataset from Natural Earth) to EPSG 3857 and adapted the example Code
from qgis.utils import iface
feature_name = '[%NAME%]'
feature_id = [%$id%]
layer_id = '[%@layer_id%]'
layer = QgsProject.instance().mapLayer(layer_id)
new_layer = layer.materialize(
QgsFeatureRequest().setFilterFids([feature_id]))
new_layer.setName(feature_name)
QgsProject.instance().addMapLayer(new_layer)
iface.setActiveLayer(layer)
for my use case as follows (considering this answer):
from qgis.utils import iface
feature_name = '[%NAME%]'
feature_id = [%$id%]
layer_id = '[%@layer_id%]'
layer = QgsProject.instance().mapLayer(layer_id)
buffer_layer = QgsVectorLayer("Polygon?crs=epsg:3857", "buffer_200km", "memory")
buffer_distance = 200000
for feature in layer.getFeatures(layer_id):
geom = feature.geometry()
country_buffer = geom.buffer(buffer_distance, 5)
f = QgsFeature()
f.setGeometry(country_buffer)
buffer_layer.dataProvider().addFeatures([f])
QgsProject.instance().addMapLayer(buffer_layer)
iface.setActiveLayer(layer)
When applying the action, I got the following error:
Traceback (most recent call last): File "", line 11, in TypeError: QgsVectorLayer.getFeatures(): arguments did not match any overloaded call: overload 1: argument 1 has unexpected type 'int' overload 2: argument 1 has unexpected type 'int' overload 3: argument 1 has unexpected type 'int' overload 4: argument 1 has unexpected type 'int'
1 Answer 1
I was able to find a working solution without the materialize method:
from qgis.utils import iface
feature_name = '[%NAME%]'
feature_id = [%$id%]
layer_id = '[%@layer_id%]'
layer = QgsProject.instance().mapLayer(layer_id)
buffer_layer = QgsVectorLayer("Polygon?crs=epsg:3857&field=fid:integer", f'{feature_name} buffer_200km', "memory")
buffer_distance = 200000
for feature in layer.getFeatures([feature_id]): # added squared brackets
geom = feature.geometry()
country_buffer = geom.buffer(buffer_distance, 5)
f = QgsFeature()
f.setGeometry(country_buffer)
buffer_layer.dataProvider().addFeatures([f])
QgsProject.instance().addMapLayer(buffer_layer)
iface.setActiveLayer(layer)
Exemplary result in map: result of custom action adding buffer layer