Utiliser pyshp pour convertir un fichier .csv en .shp?

10

J'essaie de comprendre comment je peux utiliser le module csv en python pour ouvrir un fichier csv dans le même dossier que le script python, puis créer un fichier de formes à l'aide du module shapefile pyshp.

Le fichier csv ressemble à ceci, mais peut avoir quelques milliers de lignes d'enregistrements:

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
la source

Réponses:

14

Le module pyshp est un peu difficile à comprendre, mais vraiment utile une fois que vous l'avez lancé. J'ai écrit un script qui lit dans un fichier csv des données d'exemple et écrit un fichier de formes avec les données stockées en tant qu'attributs des types de données corrects. Le type de données pyshp / xbase a toujours été délicat pour moi jusqu'à ce que je trouve ce guide de l'utilisateur pour le format xbase et à la suite de cette question, j'ai écrit une petite note sur mon blog concernant les types de données pyshp pertinents, dont j'ai collé une partie ci-dessous :

  • C est des caractères ASCII
  • N est un entier double précision limité à environ 18 caractères
  • D est pour les dates au format AAAAMMJJ, sans espaces ni tirets entre les sections.
  • F est pour les nombres à virgule flottante avec les mêmes limites de longueur que N
  • L est pour les données logiques qui sont stockées dans la table attributaire du fichier de formes sous la forme d'un entier court comme 1 (vrai) ou 0 (faux). Les valeurs qu'il peut recevoir sont 1, 0, y, n, Y, N, T, F ou les valeurs intégrées python True et False

La liste complète est la suivante:

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)

J'espère que ça aide.

sgrieve
la source
Très beau script. J'ai reçu une erreur car il ne l'a pas lu sous forme de texte, j'ai donc modifié cette ligne: avec open ('input.csv', 'rt') en tant que fichier csv:
contre
1
Je pense que vous pouvez améliorer les performances en utilisant next (r) avant la boucle for pour ignorer l'en-tête au lieu de vérifier en utilisant une instruction if.
rovyko
@sgrieve - ce script convertit un csv avec des champs prédéterminés spécifiques. Je voudrais un script générique pour convertir n'importe quel csv en classe d'entités. Peut-être existe-t-il des fonctions arcpy utiles pour y parvenir?
Waterman
2

Comme alternative, vous n'avez pas besoin de conserver les données dans des listes.

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

Vous pouvez trouver un exemple pratique de cette implémentation ici .

Clubdebambos
la source