Filtra le caratteristiche in base ai loro attributi usando Python?


16

Come ottenere funzionalità in base ai loro attributi (simili a Iqueryfilter in arcobjects) in Qgis usando Python? Invece di ottenere tutte le funzionalità e filtrarlo manualmente, c'è qualche opzione da usare dove clausola per filtrarlo?

Esempio: ho un nome campo chiamato "Contee". Ha più di cinquantamila funzionalità. Non è possibile recuperare tutte le funzionalità e filtrarle a causa del dispendio di tempo. Quindi posso interrogarlo usando iqueryfilter.whereclause = 'Counties = Norwich' in arcobjects. Una cosa simile di cui ho bisogno in PyQgis.


1
@NathanW sì, hai ragione. ho solo bisogno di restituire i dati utilizzando una query dal livello. potresti fornirmi qualche esempio in pyqgis?
Venkat,

@NathanW Ciao, ho capito. funziona come una query di definizione in arcgis. vedi questo esempio. t = outputLayer.setSubsetString ('UniqID =' + inputFeat.attribute ("UniqID"). toPyObject ()) se t == True: outputProvider = outputLayer.dataProvider () print outputProvider.featureCount () ovvero restituirà solo la query dati soddisfatti
venkat

@venkat dove in QGIS stai inserendo la query? Grazie.
ianbroad,

Risposte:


12

Il motore di espressione QGIS è in grado di farlo utilizzando il QgsFeatureRequest.setFilterExpression( unicode )metodo (da QGIS 2.2)

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

A partire da QGIS 2.10 è anche possibile che il filtraggio in questo modo ti fornisca prestazioni extra rispetto ad altri tipi di filtraggio (come le implementazioni di Python).

Fondamentalmente questo vale se sono soddisfatte le seguenti tre condizioni:

  • Stai usando un livello con il fornitore di postgis Al momento (2.16) molti altri oltre al solo fornitore di postgis implementano questo (spatialite, ogr, oracle ...).
  • La vostra espressione non è eccessivamente complicata (cose come >, =, IN, NOT NULL... sono supportati)
  • Questa funzione è stata abilitata in Impostazioni> Opzioni> Origini dati> Gestione origine dati> Esegui espressione sul lato server di postgres
  • Il vantaggio in termini di prestazioni è ottimale con indici appropriati nelle tabelle del database

Con QGIS 3.0 è anche possibile semplicemente farlo

features = l.getFeatures('"Counties" = \'Norwicth\'')

1

Questo post - che potrebbe essere considerato una risposta a una domanda duplicata - spiega come recuperare tutti gli attributi da un livello. L'autore descrive il processo che stai cercando come filtraggio manuale dei dati una volta restituiti. È un riferimento abbastanza completo e il loro link dovrebbe davvero aiutarti.


2
Questa non è una domanda duplicata. non voglio recuperare tutti gli attributi da un livello. Filtralo prima e poi voglio recuperare le funzionalità che rientrano nei criteri di filtro. cioè le prestazioni sono molto migliori.
Venkat,

1

Usando una query sql è anche facilmente possibile con ogr. È possibile eseguire questo codice ad esempio nella console python di QGIS o in uno script autonomo.
Esempio :

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'

0

La specifica dei filtri SQL non è ancora supportata utilizzando l'API QGIS dalla versione 1.9.

Come ho capito da questo articolo della mailing list , il supporto per "SQL del provider nativo" sarebbe disponibile solo in una versione futura.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.