Apa fungsi setara QGIS untuk Pembaruan / Hapus Baris / Bidang ArcPy?

8

Saya mencoba memprogram ulang beberapa skrip dari ArcPy ke QGIS (1.8 atau 2.0) dan ada beberapa fungsi sederhana yang saya ingin dapat ulang tetapi sayangnya dokumentasi di QGIS kurang di daerah tertentu.

Yaitu tiga yang paling penting bagi saya adalah:

Tambah Bidang - Tambahkan bidang

arcpy.AddField_management(Feature, "ID", "SHORT")

Hitung Manajemen Lapangan - Perbarui bidang itu

arcpy.CalculateField_management(Feature,"ID","!FID!")

Perbarui / Hapus Baris - Perbarui / Hapus baris berdasarkan kondisi (tanpa menyalin shapefile)

keep = ["Bob","Janet","John","Mike"]
Counter = 0
rows = arcpy.UpdateCursor(Feature)

for row in rows:
    if row.Name in keep:
        row.ID = Counter
        rows.updateRow(row)
    else:
        rows.deleteRow(row)
    Counter += 1

Sekarang saya dapat mengulangi setiap fitur dalam QGIS menggunakan SEXTANTE dan mendapatkan geometrinya yang seharusnya dapat saya tulis ulang menjadi shapefile baru dan dengan demikian memperbarui / menghapus baris atau bidang. Dimulai dengan sesuatu di sepanjang garis ...

layer = st.getobject(Polygon)
features = st.getfeatures(layer)
for f in features:
    f.geometry().asPolygon()

tetapi saya tidak dapat menemukan solusi sederhana untuk fungsi-fungsi yang disebutkan di atas?

BJEBN
sumber
Saya tidak yakin, apa tujuan dari bagian terakhir dari pertanyaan Anda. Mengapa Anda menyebutkan SEXTANTE? Anda meminta metode untuk menulis ulang ke dalam shapefile baru, tetapi kutipan kode Anda tidak melakukan hal seperti itu.
Matthias Kuhn

Jawaban:

16

Contoh-contoh berikut didasarkan pada API QGIS 2.0 (segera akan dirilis). Ini telah berubah sejak 1.8, jadi sintaks untuk versi ini akan berbeda di beberapa tempat.

Sumber daya terbaik untuk solusi yang sesuai dengan 1,8 dan penjelasan mendalam untuk latar belakang parameter (juga berlaku untuk 2.0) adalah Cookbook PyQGIS

Kami akan menganggap Anda sudah memiliki referensi ke lapisan vektor yang disebut vldiperoleh dengan misalnya

vl = iface.activeLayer()

Transaksi

Contoh-contoh berikut bekerja dalam suatu transaksi (secara lokal di-cache dalam QGIS). Sebelum memulai sesi edit, Anda harus menelepon

vl.startEditing()

dan akhiri dengan

vl.commitChanges()

untuk menulis perubahan Anda ke sumber data. atau

vl.rollBack()

untuk mengabaikan perubahan

Anda juga dapat bekerja secara langsung vl.dataProvider()dan melupakan pernyataan kontrol transaksi. (Menghasilkan perilaku seperti autocommit)

Menambahkan bidang

QgsVectorLayer.addAttribute (QgsField)

from PyQt4.QtCore import QVariant
vl.addAttribute( QgsField( 'fieldname', QVariant.String ) )

Ini hanya berfungsi, jika dataprovider mengimplementasikan kemampuan AddAttributes. Anda dapat memeriksanya dengan:

if vl.dataProvider().capabilities() & QgsVectorDataProvider.ChangeAttributeValues

Hitung bidang

Lihat jawaban ini:

Apakah mungkin untuk menambahkan bidang terhitung secara terprogram?

Itu masih ditujukan untuk 1.8, jadi alih-alih vl.select()Anda harus memanggil setara 2.0 vl.getFeatures()(lihat perubahan QGIS API )

Perbarui baris

QgsVectorLayer.updateField (featureId, fieldIndex, value)

vl.updateField( 1000, 5, 'hello' )

Pemeriksaan prasyarat (opsional):

if vl.dataProvider().capabilities() & QgsVectorDataProvider.ChangeAttributeValues

Untuk mengetahui fieldIndex, Anda bisa menggunakan QgsVectorLayer.pendingFields()

Sunting: Lihat juga komentar oleh NathanW yang menyebutkan QgsVectorLayer.updateFeature( feature )metode yang bisa dibaca dengan baik .

Hapus baris

QgsVectorLayer.deleteFeature (featureId)

vl.deleteFeature( 1000 )

Prasyarat opsional periksa:

if vl.dataProvider().capabilities() & QgsVectorDataProvider.DeleteFeatures
Matthias Kuhn
sumber
2
Menggunakan feature[5] = 'hello'dan layer.updateFeature(feature)lebih baik daripada menggunakan vl.updateField IMO
Nathan W
5

Ini adalah bagaimana Anda akan melakukan kode Anda di PyQGIS:

keep = ["Bob","Janet","John","Mike"]

for counter, feature in enumerate(layer.getFeatures()):
    if feature['Name'] in keep:
        feature['ID'] = counter
        layer.updateFeature(feature)
    else:
        layer.deleteFeature(feature.id())
Nathan W
sumber