¿Eliminar características seleccionadas usando PyQGIS?

8

Tengo un shapefile con solo un campo DN . Me gustaría eliminar todas las funciones que no tienen un valor específico del campo. Digamos que el DN puede ser 1,2 o 3.

Hasta ahora pude averiguar cómo seleccionar Funciones y cómo eliminar funciones, pero no logré combinarlas. Digamos que quiero que solo queden las características con DN = 3:

Selección de las características que se encuentran aquí , sin embargo, no sé si hace lo que se supone que debe hacer, ya que no encontré la forma de verificar lo que hay dentro.

select = layer.getFeatures(QgsFeatureRequest().setFilterExpression(u'"DN"!=3'))

eliminar funciones encontradas aquí

res = Ilayer.dataProvider().deleteFeatures()

Por lo que yo sé, el deleteFeatures()requiere ID de las características, pero no tengo ni idea de cómo obtenerlos a partir de selectla cual es QgsFeatureIterator.

MasterPJ
fuente

Respuestas:

18

Puede recorrer el iterador y obtener el .id()para cada característica en él:

with edit(layer):
    # build a request to filter the features based on an attribute
    request = QgsFeatureRequest().setFilterExpression('"DN" != 3')

    # we don't need attributes or geometry, skip them to minimize overhead.
    # these lines are not strictly required but improve performance
    request.setSubsetOfAttributes([])
    request.setFlags(QgsFeatureRequest.NoGeometry)

    # loop over the features and delete
    for f in layer.getFeatures(request):
        layer.deleteFeature(f.id())

O con QGIS <2.12

request = QgsFeatureRequest().setFilterExpression('"DN" != 3')
request.setSubsetOfAttributes([])
request.setFlags(QgsFeatureRequest.NoGeometry)
ids = [f.id() for f in layer.getFeatures(request)]
layer.startEditing()
for fid in ids:
    layer.deleteFeature(fid)
layer.commitChanges()
Matthias Kuhn
fuente
Gracias, eso fue todo! Me acabo de dar cuenta de que FilterExpression estaba equivocado (no se debe usar u '"DN" = 2 || "DN" = 1' pero se debe usar u '"DN"! = 3'). Por favor, si edita su respuesta para que esto no confunda a otros espectadores.
MasterPJ
¿No es layer.dataProvider (). deleteFeatures (ids)?
mbernasocchi
Es posible usar dataProvider (), pero prefiero trabajar directamente en la capa, ya que de esta manera los cambios se comunican internamente (al lienzo del mapa, la tabla de atributos ...) y otras razones .
Matthias Kuhn
2
layer.dataProvider (). deleteFeatures (ids) ha arrojado bloqueos para mí cuando layer.deleteFeature (fid) no ... Fallos incorrectos. Del tipo que causa una falla seg y mata qgis. El tipo que toma 6 horas para encontrar ... quédese con la respuesta publicada aquí. Me fastidia porque layer.dataProvider (). DeleteFeatures (ids) está en todo mi código y ahora tengo que arreglarlo todo.
Mr Purple