Usando pyshp per convertire il file .csv in .shp?


10

Sto cercando di capire come posso usare il modulo CSV in Python per aprire un file CSV nella stessa cartella dello script Python, e quindi creare un file di forma usando il modulo PFHP del modulo di forma.

Il file CSV si presenta così, ma può avere un paio di migliaia di righe di record:

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

Risposte:


14

Il modulo pyshp è un po 'complicato da capire, ma è davvero utile quando lo fai andare avanti. Ho scritto uno script che legge in un CSV i dati di esempio e scrive uno shapefile con i dati memorizzati come attributi dei tipi di dati corretti. Il tipo di dati pyshp / xbase è sempre stato complicato per me fino a quando non ho trovato questa guida per l'utente per il formato xbase e come risultato di questa domanda ho scritto una piccola nota sul mio blog riguardante i tipi di dati pyshp pertinenti, parte della quale ho incollato di seguito :

  • C è caratteri ASCII
  • N è un numero intero a doppia precisione limitato a circa 18 caratteri di lunghezza
  • D è per le date nel formato AAAAMMGG, senza spazi o trattini tra le sezioni.
  • F è per i numeri in virgola mobile con gli stessi limiti di lunghezza di N
  • L è per i dati logici memorizzati nella tabella degli attributi del file di forma come numero intero breve come 1 (vero) o 0 (falso). I valori che può ricevere sono 1, 0, y, n, Y, N, T, F o gli builtin python True e False

L'elenco completo è il seguente:

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)

Spero che questo possa essere d'aiuto.


Sceneggiatura molto bella. Ho ricevuto un errore perché non l'ho letto come testo, quindi ho cambiato questa riga: con open ('input.csv', 'rt') come csvfile:
flusso

1
Penso che puoi migliorare le prestazioni usando next (r) prima del ciclo for per saltare l'intestazione invece di controllare usando un'istruzione if.
Rovyko,

@sgrieve: questo script converte un csv con specifici campi predeterminati. Vorrei uno script generico per convertire qualsiasi CSV in una classe di funzionalità. Forse ci sono utili funzioni arcpy per raggiungere questo obiettivo?
Waterman,

2

In alternativa non è necessario conservare i dati negli elenchi.

# 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")

Puoi trovare un esempio funzionante di questa implementazione qui .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.