¿Filtrar características en función de sus atributos con Python?

16

¿Cómo obtener características por sus atributos (similar a Iqueryfilter en arcobjects) en Qgis usando python? En lugar de obtener todas las funciones y filtrarlas manualmente, ¿hay alguna opción para usar la cláusula where para filtrarla?

Ejemplo: Tengo un nombre de campo llamado 'Condados'. Tiene más de cincuenta mil funciones. No es posible obtener todas las funciones y filtrarlas debido a que lleva mucho tiempo. Entonces puedo consultarlo usando iqueryfilter.whereclause = 'Counties = Norwich' en arcobjects. Algo similar que necesito en PyQgis.

Venkat
fuente
1
@NathanW sí, tienes razón. Solo necesito devolver los datos usando una consulta de la capa. ¿podría darme algún ejemplo en pyqgis?
venkat
@NathanW Hola, lo tengo. funciona como consulta de definición en arcgis. Mira este ejemplo. t = outputLayer.setSubsetString ('UniqID =' + inputFeat.attribute ("UniqID"). toPyObject ()) if t == True: outputProvider = outputLayer.dataProvider () print outputProvider.featureCount () es decir, solo devolverá la consulta datos satisfechos
venkat
@venkat ¿en qué parte de QGIS está haciendo la consulta? Gracias.
ianbroad

Respuestas:

12

El motor de expresión QGIS puede hacer esto usando el QgsFeatureRequest.setFilterExpression( unicode )método (desde QGIS 2.2)

request = QgsFeatureRequest().setFilterExpression( u'"Counties" = \'Norwich\'' )
it = l.getFeatures( request )

Comenzando con QGIS 2.10, incluso es posible que el filtrado de esa manera le brinde un rendimiento adicional sobre otros tipos de filtrado (como las implementaciones de Python).

Básicamente esto se aplica si se cumplen las siguientes tres condiciones:

  • Está utilizando una capa con el proveedor de postgis En este momento (2.16), mucho más que solo el proveedor de postgis implementa esto (spaceialite, ogr, oracle ...).
  • Su expresión no se complica demasiado (cosas como >, =, IN, NOT NULL... son compatibles)
  • Ha habilitado esta función en Configuración> Opciones> Orígenes de datos> Manejo de origen de datos> Ejecutar expresión en el servidor postgres
  • El beneficio de rendimiento es óptimo con índices apropiados en las tablas de la base de datos.

Con QGIS 3.0 es incluso posible simplemente hacer

features = l.getFeatures('"Counties" = \'Norwicth\'')
Matthias Kuhn
fuente
1

Esta publicación , que podría considerarse una respuesta a una pregunta duplicada, detalla cómo obtener todos los atributos de una capa. El autor describe el proceso que está buscando como filtrar los datos manualmente una vez que se devuelven. Es una referencia bastante completa y su enlace realmente debería ayudarte.

Tom
fuente
2
Esta no es una pregunta duplicada. No quiero obtener todos los atributos de una capa. Primero filtre y luego quiero obtener las características que se incluyen en los criterios de filtro. es decir, el rendimiento es mucho mejor.
venkat
1

Mediante el uso de una consulta SQL también es posible con facilidad ogr. Puede ejecutar este código, por ejemplo, en la consola de Python QGIS o en un script independiente.
Ejemplo :

from osgeo import ogr

path = "path to your shapefile.shp"
ID = "FieldID" # For instance 'Countries' 
datasource = ogr.Open(str(path)) # your datasource

layer = datasource.GetLayer(0) # Import layer 0 --> only works with shapefiles
layerName = str( layer.GetName() )# Save the Layersname first

# Do the sql query
# Selects all features from a layer datasource where Field Countries is equal to 'Germany'
layers = datasource.ExecuteSQL("SELECT * FROM %s WHERE %s = '%s'" % (layerName, ID, 'Germany') )
res = []
for i in range(0,layers.GetFeatureCount()):
   f = layers.GetFeature(i)
   g = f.GetGeometryRef()
   res.append(g.Area()) 

# res now contains the measured area of each feature where the attribute ID has the value 'Germany'
Zarapito
fuente
0

La especificación de filtros SQL aún no es compatible con QGIS API a partir de la versión 1.9.

Según tengo entendido por este artículo de la lista de correo , el soporte para el "SQL del proveedor nativo" solo estará en una versión futura.

vinayan
fuente