Comment ajouter un champ d'attribut à un Shapefile existant via Python sans ArcGIS?


24

J'ai un script Python qui ajoute un champ d'attribut à un Shapefile s'il n'existe pas. C'est facile à faire avec ArcGIS (graphiquement ou via Python), mais je recherche quelque chose qui ne dépend pas d'ArcGIS.

J'ai essayé cela sans succès avec OGR, car mon Shapefile contient des fonctionnalités .

J'ai regardé pyshp , mais de même, il n'y a aucun moyen de modifier le schéma après sa création. Je n'ai pas essayé avec le fichier de formes (pour Python) , mais je ne vois pas cette fonctionnalité annoncée. Je ne vois pas non plus comment cela peut être fait en bricolant le fichier DBF via dbfpy .

Quelqu'un a-t-il une idée?


Serait-il acceptable de cloner la structure de fichier de formes existante, d'ajouter une nouvelle colonne, puis de la remplir en fonction du fichier de formes d'origine?
DavidF


Cette question doit être fermée en tant que doublon de gis.stackexchange.com/q/3623/664 .
whuber

Oui, essentiellement la même chose. J'ai regardé, mais je ne l'ai pas vu.
Mike T

Réponses:


8

vous devriez jeter un coup d'œil à ces questions car il a déjà été répondu: Comment ajouter des attributs de fonctionnalité personnalisés à Shapefile en utilisant Python?

/programming/4215658/adding-custom-feature-attributes-to-esri-shapefile-with-python

Si vous voulez comme résultat, un seul fichier de formes, supprimez simplement vos fichiers d'entrée à la fin de votre script.


Qui est également similaire à gis.stackexchange.com/questions/3623/… Merci d'avoir déterré cela
Mike T


4

Grâce à un format plutôt cérébral appelé DBF, l'ajout de champs aux fichiers de formes avec les données d'attribut existantes n'est pas possible sans réécriture ou ajout de remplissage au DBF. Je ne connais pas de solution toute faite, mais ce que je ferais serait d'écrire un script pour créer un nouveau fichier de formes basé sur un existant et d'ajouter le ou les champs supplémentaires au nouveau fichier de formes. Copiez ensuite les données de géométrie / attribut de l'ancien vers le nouveau fichier de formes. Et comme dernière étape, supprimez l'ancien fichier de formes et renommez le nouveau. Tout cela est assez facilement accompli en utilisant des liaisons python OGR.

Alternativement, vous pouvez utiliser dbfpy pour faire ce qui précède avec juste le fichier DBF. L'ordre des étapes reste le même:

  1. Créer un nouveau DBF avec une structure identique à l'original
  2. Créer de nouveaux champs d'attribut dans le nouveau DBF
  3. Copiez les données du DBF d'origine vers le nouveau DBF
  4. Supprimer l'ancien DBF, renommer le nouveau DBF en ancien DBF

Vous n'avez pas besoin de modifier le fichier de formes (.shp) lui-même ni aucun des autres fichiers, car ils ne font pas référence aux informations d'attribut contenues dans le DBF. Vous devez cependant conserver l'ordre des enregistrements exactement le même dans l'ancien et le nouveau DBF.


3

DBFpy devrait fonctionner pour cela. Avez-vous vu un exemple sur cette page:

http://dbfpy.sourceforge.net/

Assurez-vous que le fichier de formes n'est pas en cours de modification par une autre application, y compris ArcGIS, car cela peut entraîner des problèmes via le verrouillage.


Je ne pense pas que cela fonctionne si vous avez déjà des données dans le fichier DBF. Je l'avais déjà regardé, mais j'obtiens une erreur: "Au moins un enregistrement a été ajouté, la structure ne peut pas être modifiée". Avez-vous un exemple précis en tête?
Mike T

Ah je me souviens maintenant oui car Sasa a dit que la création d'un nouveau DBF serait nécessaire. Copiez le schéma (comme dans les champs, etc.) à travers puis faites vos ajouts, puis copiez les enregistrements à travers. Le "grand" DBF ... :(
Rob Clark

@Mike Comment un enregistrement a-t-il été ajouté alors que tout ce que vous voulez faire est d'ajouter un champ ?? L'ajout d'un enregistrement est une erreur car il ruine la connexion entre les attributs et les formes. L'ajout d'un champ ne fait aucun mal. Toute bibliothèque capable de modifier des fichiers dbf fera le travail correctement.
whuber

@whuber: C'est leur message d'erreur. Ouvrez un dbf existant qui contient des données et voyez:from dbfpy import dbf; db = dbf.Dbf('my.dbf'); db.addField(("FOO", "C", 15))
Mike T

@Mike Merci d'avoir clarifié la situation. Cela ressemble au résultat d'une limitation inutile dans dbfpy :-(. Je peux deviner pourquoi: l'ajout d'un champ dans une base de données non vide nécessite que tous les enregistrements soient physiquement lus, développés et réécrits. Une bonne solution est pour trouver une bibliothèque dBase différente ou utiliser un autre logiciel ;-).
whuber

1

J'ai trouvé une solution en utilisant OGR et grâce à l'aide d'une question précédente . Voici un exemple complet:

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

Mon problème était que j'utilisais layer_defn.AddFieldDefn(new_field)plutôt que layer.CreateField(new_field). Un grand merci à l'aide et désolé de ne pas avoir vérifié l'autre question similaire.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.