Memfilter fitur berdasarkan atributnya menggunakan Python?


16

Bagaimana cara Mendapatkan fitur berdasarkan atributnya (mirip dengan Iqueryfilter di arcobjects) di Qgis menggunakan python? Alih-alih mendapatkan semua fitur dan memfilternya secara manual, apakah ada opsi untuk menggunakan tempat klausa untuk memfilternya?

Contoh: Saya memiliki nama bidang yang disebut 'Kabupaten'. Ini memiliki lebih dari lima puluh ribu fitur. Yaitu tidak mungkin mengambil semua fitur dan memfilternya karena memakan waktu. Jadi saya bisa menanyakannya dengan menggunakan iqueryfilter.whereclause = 'Counties = Norwich' di arcobjects. Hal serupa yang saya butuhkan di PyQgis.


1
@NathanW ya Anda benar. saya hanya perlu mengembalikan data menggunakan kueri dari layer. bisa tolong berikan saya contoh di pyqgis?
venkat

@NathanW Hai saya mengerti. itu berfungsi seperti query definisi di arcgis. lihat contoh ini. t = outputLayer.setSubsetString ('UniqID =' + inputFeat.attribute ("UniqID"). toPyObject ()) jika t == Benar: outputProvider = outputLayer.dataProvider () cetak outputProvider.featureCount () yaitu hanya akan mengembalikan permintaan data puas
venkat

@venkat di mana di QGIS Anda menempatkan kueri? Terima kasih.
ianbroad

Jawaban:


12

Mesin ekspresi QGIS dapat melakukan ini menggunakan QgsFeatureRequest.setFilterExpression( unicode )metode (Sejak QGIS 2.2)

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

Dimulai dengan QGIS 2.10 bahkan mungkin bahwa pemfilteran sedemikian rupa akan memberi Anda beberapa kinerja ekstra dibandingkan jenis pemfilteran lainnya (seperti implementasi python).

Pada dasarnya ini berlaku jika tiga kondisi berikut dipenuhi:

  • Anda menggunakan layer dengan penyedia postgis. Saat ini (2.16), lebih banyak dari sekadar penyedia postgis yang mengimplementasikan ini (spatialite, ogr, oracle ...).
  • Ekspresi Anda tidak terlalu rumit (hal-hal seperti >, =, IN, NOT NULL... yang didukung)
  • Anda telah mengaktifkan fitur ini di Pengaturan> Opsi> Sumber Data> Penanganan Sumber Data> Jalankan ekspresi di sisi server postgres
  • Manfaat kinerja optimal dengan indeks yang sesuai pada tabel database

Dengan QGIS 3.0 bahkan dimungkinkan untuk melakukannya

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

1

Posting ini - yang dapat dianggap sebagai jawaban untuk pertanyaan duplikat - merinci cara mengambil semua atribut dari sebuah layer. Penulis menjelaskan proses yang Anda cari sebagai memfilter data secara manual setelah dikembalikan. Ini adalah referensi yang cukup lengkap dan tautannya akan sangat membantu Anda.


2
Ini bukan pertanyaan rangkap. saya tidak ingin mengambil semua atribut dari sebuah layer. Saring dulu dan kemudian saya ingin mengambil fitur yang ada di bawah kriteria saringan. yaitu kinerjanya jauh lebih baik.
venkat

1

Dengan menggunakan query sql juga mudah mungkin dengan ogr. Anda dapat menjalankan kode ini misalnya di konsol python QGIS atau skrip mandiri.
Contoh :

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

Menentukan filter SQL belum didukung menggunakan QGIS API pada versi 1.9.

Seperti yang saya pahami dari artikel milis ini , dukungan untuk "SQL penyedia asli" hanya akan ada di rilis mendatang.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.