1

By means of a PyQGIS layer action, I am looking for a way to select all polygon features within a buffer polygon sharing a certain field value (e. g. provinces belonging to the same country) with the feature I have clicked on. I got stuck in the part of the code combining the getFeatures method with a selecting expression, which throws the following TypeError:

Traceback (most recent call last):
  File "", line 26, in 
TypeError: QgsFeatureRequest(): arguments did not match any overloaded call:
  overload 1: too many arguments
  overload 2: argument 1 has unexpected type 'str'
  overload 3: argument 1 has unexpected type 'str'
  overload 4: argument 1 has unexpected type 'str'
  overload 5: argument 1 has unexpected type 'str'
  overload 6: argument 1 has unexpected type 'str'

The full code is:

from qgis.utils import iface
        
layer_id = '[%@layer_id%]'
feature_id = [%$id%]
feature_name = '[%name%]'
field_name = 'iso_a2'
field_value = '[%iso_a2%]'
expression = f'"{field_name}" = \'{field_value}\''
   
layer = QgsProject.instance().mapLayer(layer_id)

buffer_layer = QgsVectorLayer("Polygon?crs=epsg:3857&field=fid:integer", f'{feature_name}_buffer_500km', "memory")
buffer_layer.setCrs(QgsCoordinateReferenceSystem(3857))

buffer_distance = 500000
for feature in layer.getFeatures([feature_id]):
    geom = feature.geometry()
    buffer = geom.buffer(buffer_distance, 5)

f = QgsFeature()
f.setGeometry(buffer)
buffer_layer.dataProvider().addFeatures([f])
QgsProject.instance().addMapLayer(buffer_layer)
iface.setActiveLayer(layer)

layer2 = layer.getFeatures(QgsFeatureRequest(expression)) # This line throws the TypeError
intersecting_features = [
                    p.id() 
                    for p in layer.getFeatures(buffer.boundingBox())
                    if p.geometry().intersects(buffer)
                    ]
if intersecting_features:
    layer2.selectByIds(intersecting_features)

Data for this working example comes from the natural earth data set, layer: ne_50m_admin_1_states_provinces (used crs: 3857)

How has the code to be changed in order to get the intended result?

1 Answer 1

0

With the help of this answer, I finally found a solution:

from qgis.utils import iface
        
layer_id = '[%@layer_id%]'
feature_id = [%$id%]
feature_name = '[%name%]'
field_name = 'iso_a2'
field_value = '[%iso_a2%]'
expression = f'"{field_name}" = \'{field_value}\''
   
layer = QgsProject.instance().mapLayer(layer_id)

buffer_layer = QgsVectorLayer("Polygon?crs=epsg:3857&field=fid:integer", f'{feature_name}_buffer_500km', "memory")
buffer_layer.setCrs(QgsCoordinateReferenceSystem(3857))

buffer_distance = 500000
for feature in layer.getFeatures([feature_id]):
    geom = feature.geometry()
    buffer = geom.buffer(buffer_distance, 5)

f = QgsFeature()
f.setGeometry(buffer)
buffer_layer.dataProvider().addFeatures([f])
QgsProject.instance().addMapLayer(buffer_layer)
iface.setActiveLayer(layer)

intersecting_countries_ids = [
    c.id()
    for c in layer.getFeatures(buffer.boundingBox())
    if (c.geometry().intersects(buffer)
    )
    ]
if intersecting_countries_ids:
    layer.selectByIds(intersecting_countries_ids)
layer.selectByExpression(expression, QgsVectorLayer.IntersectSelection)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.