Filtrar recursos com base em seus atributos usando Python?

16

Como obter recursos por seus atributos (semelhantes ao Iqueryfilter em arcobjects) no Qgis usando python? Em vez de obter todos os recursos e filtrá-lo manualmente, existe alguma opção para usar a cláusula where para filtrá-lo?

Exemplo: Eu tenho um nome de campo chamado 'Condados'. Ele possui mais de cinquenta mil recursos. Não é possível buscar todos os recursos e filtrá-lo por causa do tempo gasto. Para que eu possa consultá-lo usando iqueryfilter.whereclause = 'Counties = Norwich' em objetos de arcada. Coisa semelhante que eu preciso no PyQgis.

Venkat
fonte
1
@NathanW sim, você está correto. Eu só preciso retornar os dados usando uma consulta da camada. você poderia me dar algum exemplo em pyqgis?
Venkat
@NathanW Oi, eu entendi. está funcionando como consulta de definição em arcgis. veja este exemplo. t = outputLayer.setSubsetString ('UniqID =' + inputFeat.attribute ("UniqID"). toPyObject ()) se t == True: outputProvider = outputLayer.dataProvider () imprime outputProvider.featureCount () ou seja, retornará a consulta apenas dados satisfeitos
venkat
@venkat onde no QGIS você está colocando a consulta? Obrigado.
Ianbroad

Respostas:

12

O mecanismo de expressão QGIS é capaz de fazer isso usando o QgsFeatureRequest.setFilterExpression( unicode )método (Desde o QGIS 2.2)

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

A partir do QGIS 2.10, é possível que a filtragem dessa maneira ofereça um desempenho extra em relação a outros tipos de filtragem (como implementações em python).

Basicamente, isso se aplica se as três condições a seguir forem atendidas:

  • Você está usando uma camada com o provedor postgis No momento (2.16), muito mais do que o provedor postgis implementa isso (spatialite, ogr, oracle ...).
  • Sua expressão não é excessivamente complicado (coisas como >, =, IN, NOT NULL... são suportados)
  • Você ativou esse recurso em Configurações> Opções> Fontes de dados> Manipulação da fonte de dados> Executar expressão no servidor do postgres
  • O benefício de desempenho é ideal com índices apropriados nas tabelas do banco de dados

Com o QGIS 3.0, é ainda possível simplesmente fazer

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

Esta postagem - que pode ser considerada uma resposta a uma pergunta duplicada - detalha como buscar todos os atributos de uma camada. O autor descreve o processo que você está procurando como filtrando os dados manualmente depois que eles são retornados. É uma referência bastante completa e o link deles realmente deve ajudá-lo.

Tom
fonte
2
Esta não é uma pergunta duplicada. Eu não quero buscar todos os atributos de uma camada. Filtre-o primeiro e, em seguida, quero buscar os recursos que estão sob os critérios de filtro. ou seja, o desempenho é muito melhor.
Venkat
1

Usando uma consulta sql, também é possível com facilidade ogr. Você pode executar esse código, por exemplo, no console python do QGIS ou em um script independente.
Exemplo :

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'
Maçarico
fonte
0

A especificação de filtros SQL ainda não é suportada usando a API QGIS a partir da versão 1.9.

Pelo que entendi neste artigo da lista de discussão , o suporte ao "SQL do provedor nativo" seria apenas em uma versão futura.

vinayan
fonte