Wie füge ich ein Attributfeld zu einem vorhandenen Shapefile über Python ohne ArcGIS hinzu?

24

Ich habe ein Python-Skript, das einem Shapefile ein Attributfeld hinzufügt, wenn es nicht existiert. Dies ist mit ArcGIS (grafisch oder über Python) leicht möglich, ich suche jedoch nach etwas, das nicht von ArcGIS abhängt.

Ich habe dies mit OGR erfolglos versucht , da mein Shapefile Funktionen enthält .

Ich habe mir pyshp angesehen , aber auf ähnliche Weise gibt es keine Möglichkeit, das Schema zu ändern, nachdem es erstellt wurde. Ich habe es noch nicht mit Shapefile (für Python) versucht, aber ich sehe keine Werbung für diese Funktion. Ich kann auch nicht sehen, wie dies durch Basteln mit der DBF-Datei über dbfpy erfolgen kann .

Hat jemand irgendwelche Ideen?

Mike T
quelle
Ist es akzeptabel, die vorhandene Shapefile-Struktur zu klonen, eine neue Spalte hinzuzufügen und sie dann auf der Grundlage des ursprünglichen Shapefiles zu füllen?
DavidF
Diese Frage sollte als Duplikat von gis.stackexchange.com/q/3623/664 geschlossen werden .
whuber
Ja, im Wesentlichen dasselbe. Ich habe geschaut, es aber nicht gesehen.
Mike T

Antworten:

4

Dank eines verblüffenden Formats namens DBF ist das Hinzufügen von Feldern zu Shapefiles mit vorhandenen Attributdaten nicht möglich, ohne dass das DBF neu geschrieben oder aufgefüllt werden muss. Ich kenne keine fertige Lösung, aber ich würde ein Skript schreiben, um ein neues Shapefile auf der Grundlage eines vorhandenen Shapefiles zu erstellen und dem neuen Shapefile die zusätzlichen Felder hinzuzufügen. Kopieren Sie dann die Geometrie- / Attributdaten aus dem alten in das neue Shapefile. Entfernen Sie als letzten Schritt das alte Shapefile und benennen Sie das neue um. All dies ist mit OGR-Python-Bindungen ziemlich einfach zu bewerkstelligen.

Alternativ können Sie dbfpy verwenden, um das Obige nur mit der DBF-Datei auszuführen. Die Reihenfolge der Schritte bleibt gleich:

  1. Erstellen Sie einen neuen DBF mit identischer Struktur zum Original
  2. Erstellen Sie neue Attributfelder im neuen DBF
  3. Kopieren Sie Daten aus dem ursprünglichen DBF in den neuen DBF
  4. Entfernen Sie altes DBF, benennen Sie neues DBF zu altem DBF um

Sie müssen keine Änderungen am Shapefile (.shp) selbst oder an den anderen Dateien vornehmen, da diese nicht auf die im DBF enthaltenen Attributinformationen verweisen. Sie müssen jedoch die Reihenfolge der Datensätze im alten und im neuen DBF genau gleich halten.

Sasa Ivetic
quelle
3

DBFpy sollte dafür funktionieren. Hast du dann Beispiel auf dieser Seite gesehen:

http://dbfpy.sourceforge.net/

Stellen Sie sicher, dass das Shapefile derzeit von keiner anderen Anwendung, einschließlich ArcGIS, bearbeitet wird, da dies zu Problemen beim Sperren führen kann.

Rob Clark
quelle
Ich denke nicht, dass dies funktioniert, wenn Sie bereits Daten in der DBF-Datei haben. Ich habe es mir schon einmal angesehen, aber es wird eine Fehlermeldung angezeigt: "Mindestens ein Datensatz wurde hinzugefügt, die Struktur kann nicht geändert werden." Haben Sie ein konkretes Beispiel im Sinn?
Mike T
Ah, ich erinnere mich jetzt, ja, da Sasa sagte, dass die Erstellung eines neuen DBF erforderlich wäre. Kopieren Sie das Schema (wie in Feldern usw.) nach, fügen Sie es hinzu und kopieren Sie die Datensätze nach. Die "große" DBF ... :(
Rob Clark
@Mike Wie wurde ein Datensatz hinzugefügt, wenn Sie nur ein Feld hinzufügen möchten ? Das Hinzufügen eines Datensatzes ist ein Fehler, da dadurch die Verbindung zwischen den Attributen und den Formen unterbrochen wird. Das Hinzufügen eines Feldes schadet überhaupt nicht. Jede Bibliothek, die DBF-Dateien bearbeiten kann, erledigt die Aufgabe ordnungsgemäß.
whuber
@whuber: Das ist ihre Fehlermeldung. Öffnen Sie eine vorhandene DBF mit Daten und sehen Sie:from dbfpy import dbf; db = dbf.Dbf('my.dbf'); db.addField(("FOO", "C", 15))
Mike T
@ Mike Danke für die Klärung der Situation. Das klingt wie das Ergebnis einer unnötigen Einschränkung in dbfpy :-(. Ich kann mir vorstellen, warum: Wenn Sie ein Feld in eine nicht leere Datenbank einfügen, müssen alle Datensätze physisch gelesen, erweitert und wieder ausgeschrieben werden. Eine gute Lösung ist um eine andere dBase-Bibliothek zu finden oder eine andere Software zu verwenden ;-).
whuber
1

Ich habe mit OGR eine Lösung gefunden und dank der Hilfe einer früheren Frage . Hier ist ein vollständiges Beispiel:

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

Mein Problem war, dass ich layer_defn.AddFieldDefn(new_field)eher benutzte als layer.CreateField(new_field). Vielen Dank an die Hilfe, und entschuldigen Sie, dass Sie nicht genau nach der ähnlichen anderen Frage gesucht haben.

Mike T
quelle