¿Usa pyshp para convertir un archivo .csv a .shp?

10

Estoy tratando de entender cómo puedo usar el módulo csv en python para abrir un archivo csv en la misma carpeta que el script python, y luego crear un shapefile usando el módulo shapefile pyshp.

El archivo csv se ve así, pero puede tener un par de miles de filas de registros:

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
fuente

Respuestas:

14

El módulo pyshp es un poco difícil de entender, pero realmente útil una vez que lo pone en marcha. He escrito un script que lee en un csv de los datos de ejemplo y escribe un archivo de forma con los datos almacenados como atributos de los tipos de datos correctos. El tipo de datos pyshp / xbase siempre ha sido complicado para mí hasta que encontré esta guía del usuario para el formato xbase y, como resultado de esta pregunta, he escrito una pequeña nota en mi blog sobre los tipos de datos relevantes de pyshp, parte de los cuales he pegado a continuación :

  • C es caracteres ASCII
  • N es un entero de doble precisión limitado a alrededor de 18 caracteres de longitud
  • D es para fechas en el formato AAAAMMDD, sin espacios ni guiones entre las secciones.
  • F es para números de coma flotante con los mismos límites de longitud que N
  • L es para datos lógicos que se almacenan en la tabla de atributos del archivo de forma como un entero corto como 1 (verdadero) o 0 (falso). Los valores que puede recibir son 1, 0, y, n, Y, N, T, F o las construcciones de pitón Verdadero y Falso

El listado completo es el siguiente:

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)

Espero que esto ayude.

sgrieve
fuente
Muy buen guión. Obtuve un error porque no lo leía como texto, así que cambié esta línea: con open ('input.csv', 'rt') como csvfile:
againstflow
1
Creo que puede mejorar el rendimiento utilizando next (r) antes del ciclo for para omitir el encabezado en lugar de verificar con una instrucción if.
rovyko
@sgrieve: este script convierte un csv con campos predeterminados específicos. Me gustaría que un script genérico convierta cualquier csv en una clase de entidad. ¿Quizás hay funciones útiles de arcpy para lograr esto?
Waterman
2

Como alternativa, no necesita mantener los datos en listas.

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

Puede encontrar un ejemplo funcional de esta implementación aquí .

Clubdebambos
fuente