Verwenden Sie pyshp, um eine CSV-Datei in eine SHP-Datei zu konvertieren?

10

Ich versuche zu verstehen, wie ich das CSV-Modul in Python verwenden kann, um eine CSV-Datei im selben Ordner wie das Python-Skript zu öffnen und dann mit dem Shapefile-Modul pyshp ein Shapefile zu erstellen.

Die CSV-Datei sieht folgendermaßen aus, kann jedoch einige tausend Datensatzzeilen enthalten:

id_nr;date;target;start_lat;start_lon
1;2012-05-21;navpoint 25x;55.123654;13.456954
1;2012-05-23;navpoint 11f;55.143654;12.456954
Kogia
quelle

Antworten:

14

Das Pyshp-Modul ist etwas schwierig zu verstehen, aber sehr nützlich, wenn Sie es erst einmal in Gang gebracht haben. Ich habe ein Skript geschrieben, das eine CSV der Beispieldaten einliest und ein Shapefile mit den Daten schreibt, die als Attribute der richtigen Datentypen gespeichert sind. Das Pyshp / xbase-Datentyping war für mich immer schwierig, bis ich dieses Benutzerhandbuch für das xbase-Format gefunden habe. Als Ergebnis dieser Frage habe ich in meinem Blog einen kleinen Hinweis zu den relevanten Pyshp-Datentypen geschrieben, von denen ich einen Teil unten eingefügt habe ::

  • C ist ASCII-Zeichen
  • N ist eine Ganzzahl mit doppelter Genauigkeit, die auf etwa 18 Zeichen begrenzt ist
  • D steht für Datumsangaben im Format JJJJMMTT ohne Leerzeichen oder Bindestriche zwischen den Abschnitten.
  • F steht für Gleitkommazahlen mit den gleichen Längengrenzen wie N.
  • L steht für logische Daten, die in der Attributtabelle des Shapefiles als kurze Ganzzahl als 1 (wahr) oder 0 (falsch) gespeichert sind. Die Werte, die es empfangen kann, sind 1, 0, y, n, Y, N, T, F oder die in True und False integrierten Python-Werte

Die vollständige Liste lautet wie folgt:

import shapefile as shp
import csv

out_file = 'GPS_Pts.shp'

#Set up blank lists for data
x,y,id_no,date,target=[],[],[],[],[]

#read data from csv file and store in lists
with open('input.csv', 'rb') as csvfile:
    r = csv.reader(csvfile, delimiter=';')
    for i,row in enumerate(r):
        if i > 0: #skip header
            x.append(float(row[3]))
            y.append(float(row[4]))
            id_no.append(row[0])
            date.append(''.join(row[1].split('-')))#formats the date correctly
            target.append(row[2])

#Set up shapefile writer and create empty fields
w = shp.Writer(shp.POINT)
w.autoBalance = 1 #ensures gemoetry and attributes match
w.field('X','F',10,8)
w.field('Y','F',10,8)
w.field('Date','D')
w.field('Target','C',50)
w.field('ID','N')

#loop through the data and write the shapefile
for j,k in enumerate(x):
    w.point(k,y[j]) #write the geometry
    w.record(k,y[j],date[j], target[j], id_no[j]) #write the attributes

#Save shapefile
w.save(out_file)

Ich hoffe das hilft.

sgrieve
quelle
Sehr schönes Drehbuch. Ich habe eine Fehlermeldung erhalten, da es nicht als Text gelesen wurde, also habe ich diese Zeile geändert: mit open ('input.csv', 'rt') als csvfile:
gegen den
1
Ich denke, Sie können die Leistung verbessern, indem Sie next (r) vor der for-Schleife verwenden, um den Header zu überspringen, anstatt mit einer if-Anweisung zu prüfen.
Dexgecko
@sgrieve - Dieses Skript konvertiert eine CSV mit bestimmten vordefinierten Feldern. Ich möchte ein generisches Skript, um jede CSV in eine Feature-Class zu konvertieren. Vielleicht gibt es nützliche Arcpy-Funktionen, um dies zu erreichen?
Waterman
2

Alternativ müssen Sie die Daten nicht in Listen speichern.

# import libraries
import shapefile, csv

# create a point shapefile
output_shp = shapefile.Writer(shapefile.POINT)
# for every record there must be a corresponding geometry.
output_shp.autoBalance = 1
# create the field names and data type for each.
# you can insert or omit lat-long here
output_shp('Date','D')
output_shp('Target','C',50)
output_shp('ID','N')
# count the features
counter = 1
# access the CSV file
with open('input.csv', 'rb') as csvfile:
    reader = csv.reader(csvfile, delimiter=',')
    # skip the header
    next(reader, None)
    #loop through each of the rows and assign the attributes to variables
    for row in reader:
        id= row[0]
        target= row[1]
        date = row[2]
        # create the point geometry
        output_shp.point(float(longitude),float(latitude))
        # add attribute data
        output_shp.record(id, target, date)
        print "Feature " + str(counter) + " added to Shapefile."
        counter = counter + 1
# save the Shapefile
output_shp.save("output.shp")

Ein funktionierendes Beispiel für diese Implementierung finden Sie hier .

Clubdebambos
quelle