Bagaimana cara menambahkan bidang atribut ke Shapefile yang ada melalui Python tanpa ArcGIS?

24

Saya memiliki skrip Python yang menambahkan bidang atribut ke Shapefile jika tidak ada. Ini mudah dilakukan dengan ArcGIS (grafis atau melalui Python), tetapi saya sedang mencari sesuatu yang tidak bergantung pada ArcGIS.

Saya mencoba ini tidak berhasil dengan OGR, karena Shapefile saya berisi fitur .

Saya telah melihat pyshp , tetapi juga tidak ada cara untuk memodifikasi skema setelah dibuat. Saya belum pernah mencoba dengan shapefile (untuk Python) , tetapi saya tidak melihat fitur ini diiklankan. Saya juga tidak bisa melihat bagaimana hal ini dapat dilakukan dengan bermain-main dengan file DBF via dbfpy .

Adakah yang punya ide?

Mike T
sumber
Apakah dapat diterima untuk mengkloning struktur shapefile yang ada, menambah kolom baru, dan kemudian mengisinya berdasarkan pada shapefile asli?
DavidF
Pertanyaan ini harus ditutup sebagai duplikat dari gis.stackexchange.com/q/3623/664 .
whuber
Ya, pada dasarnya sama. Saya melihat, tetapi tidak melihatnya.
Mike T

Jawaban:

4

Berkat format yang agak mati otak yang disebut DBF, menambahkan bidang ke shapefile dengan data atribut yang ada tidak mungkin tanpa menulis ulang atau menambahkan padding ke DBF. Saya tidak tahu solusi yang sudah jadi, tetapi apa yang akan saya lakukan adalah menulis skrip untuk membuat shapefile baru berdasarkan yang sudah ada dan menambahkan bidang tambahan ke shapefile baru. Kemudian salin data atribut / geometri dari yang lama ke bentuk yang baru. Dan sebagai langkah terakhir, hapus shapefile lama, dan ganti nama yang baru. Semua ini cukup mudah dilakukan menggunakan binding python OGR.

Sebagai alternatif, Anda dapat menggunakan dbfpy untuk melakukan hal di atas hanya dengan file DBF. Urutan langkah tetap sama:

  1. Buat DBF baru dengan struktur yang identik dengan aslinya
  2. Buat bidang atribut baru di DBF baru
  3. Salin data dari DBF asli ke DBF baru
  4. Hapus DBF lama, ganti nama DBF baru menjadi DBF lama

Anda tidak perlu membuat perubahan apa pun pada shapefile (.shp) itu sendiri atau file lainnya, karena mereka tidak mereferensikan informasi atribut yang terkandung dalam DBF. Namun Anda perlu menjaga urutan catatan persis sama di DBF lama dan yang baru.

Sasa Ivetic
sumber
3

DBFpy harus bekerja untuk ini. Pernahkah Anda melihat contoh di halaman ini:

http://dbfpy.sourceforge.net/

Pastikan shapefile tidak sedang diedit oleh aplikasi lain termasuk ArcGIS pada saat itu karena ini dapat menyebabkan masalah melalui penguncian.

Rob Clark
sumber
Saya tidak berpikir ini berfungsi jika Anda sudah memiliki data dalam file DBF. Saya telah melihatnya sebelumnya, tetapi saya mendapatkan kesalahan: "Setidaknya satu catatan ditambahkan, struktur tidak dapat diubah". Apakah Anda memiliki contoh spesifik dalam pikiran?
Mike T
Ah saya ingat sekarang ya karena Sasa mengatakan penciptaan DBF baru akan diperlukan. Salin skema (seperti di bidang dll.) Di kemudian buat tambahan Anda, lalu salin catatan di. DBF "hebat" ... :(
Rob Clark
@ Mike Bagaimana catatan ditambahkan ketika semua yang ingin Anda lakukan adalah menambahkan bidang ?? Menambahkan catatan adalah kesalahan karena merusak koneksi antara atribut dan bentuk. Menambahkan bidang tidak ada salahnya sama sekali. Setiap perpustakaan yang dapat mengedit file dbf akan melakukan pekerjaan dengan benar.
whuber
@whuber: Itu adalah pesan kesalahan mereka. Buka dbf yang sudah ada yang memiliki data dan lihat:from dbfpy import dbf; db = dbf.Dbf('my.dbf'); db.addField(("FOO", "C", 15))
Mike T
@ Mike Terima kasih telah menjelaskan situasi. Kedengarannya seperti hasil dari pembatasan yang tidak perlu di dbfpy :-(. Saya bisa menebak mengapa: menambahkan bidang dalam database yang tidak kosong mengharuskan semua catatan dibaca, diperluas, dan ditulis kembali secara fisik. Solusi yang bagus adalah untuk menemukan perpustakaan dBase yang berbeda atau menggunakan perangkat lunak lain ;-).
whuber
1

Saya menemukan solusi menggunakan OGR dan terima kasih untuk membantu dari pertanyaan sebelumnya . Ini adalah contoh lengkapnya:

from osgeo import ogr

# Open a Shapefile, and get field names
source = ogr.Open('my.shp', update=True)
layer = source.GetLayer()
layer_defn = layer.GetLayerDefn()
field_names = [layer_defn.GetFieldDefn(i).GetName() for i in range(layer_defn.GetFieldCount())]
print len(field_names), 'MYFLD' in field_names

# Add a new field
new_field = ogr.FieldDefn('MYFLD', ogr.OFTInteger)
layer.CreateField(new_field)

# Close the Shapefile
source = None

Masalah saya adalah bahwa saya menggunakan layer_defn.AddFieldDefn(new_field)daripada layer.CreateField(new_field). Terima kasih banyak atas bantuannya, dan maaf karena tidak memeriksa pertanyaan lain yang serupa.

Mike T
sumber