Obtenir les noms de champs des fichiers de formes à l'aide de GDAL


15

J'utilise GDAL en Python pour importer des fichiers de formes. Je veux connaître les noms de champs pour le fichier, ma façon actuelle est:

fields = []
for i in range(1, layer.GetFeature(0).GetFieldCount()):
    field = layer.GetFeature(0).GetDefnRef().GetFieldDefn(i).GetName()
    fields.append(field)

Mais de cette façon, j'obtiens la fonctionnalité pour la première couche. Cela signifie-t-il qu'il est possible que différentes couches puissent avoir des caractéristiques différentes?

Sinon, est-il possible d'obtenir les noms de champs à la fois, au lieu d'entrer dans cette profondeur? Si oui, existe-t-il un moyen plus simple d'obtenir les noms des champs?


Le fichier de formes n'a toujours qu'un seul calque. Je crois également que chaque fonctionnalité a les mêmes attributs, il suffit donc de vérifier uniquement la première fonctionnalité.
user30184

Réponses:


24

1) fichier de formes individuel: comme dans le commentaire, un fichier de formes n'a qu'un seul calque. Si vous ne voulez que les noms des champs

from osgeo import ogr
source = ogr.Open("a_shapefile.shp")
layer = source.GetLayer()
schema = []
ldefn = layer.GetLayerDefn()
for n in range(ldefn.GetFieldCount()):
    fdefn = ldefn.GetFieldDefn(n)
    schema.append(fdefn.name)
print schema
['dip_dir', 'dip', 'cosa', 'sina']

Vous pouvez utiliser le format GeoJSON avec un générateur Python ( ogr_geointerface.py )

def records(layer):  
    # generator 
    for i in range(layer.GetFeatureCount()):
        feature = layer.GetFeature(i)
        yield json.loads(feature.ExportToJson())
features = record(layer)
first_feat = features.next()
print first_feat
{u'geometry': {u'type': u'Point', u'coordinates': [272070.600041, 155389.38792]}, u'type': u'Feature', u'properties': {u'dip_dir': 130, u'dip': 30, u'cosa': -0.6428, u'sina': -0.6428}, u'id': 0}
print first_feat['properties'].keys()
[u'dip', u'dip_dir', u'cosa', u'sina']

Cela introduit Fiona (un autre wrapper Python d'OGR, Python 2.7.x et 3.x). Tous les résultats sont des dictionnaires Python (format GeoJSON).

import fiona
shapes = fiona.open("a_shapefile.shp")
shapes.schema
{'geometry': 'Point', 'properties': OrderedDict([(u'dip_dir', 'int:3'), (u'dip', 'int:2'), (u'cosa', 'float:11.4'), (u'sina', 'float:11.4')])}
shapes.schema['properties'].keys()
[u'dip', u'dip_dir', u'cosa', u'sina']
# first feature
shapes.next()
{'geometry': {'type': 'Point', 'coordinates': (272070.600041, 155389.38792)}, 'type': 'Feature', 'id': '0', 'properties': OrderedDict([(u'dip_dir', 130), (u'dip', 30), (u'cosa', -0.6428), (u'sina', -0.6428)])}

Et GeoPandas (Fiona + pandas , Python 2.7.x et 3.x). Le résultat est un Pandas DataFrame (= GeoDataFrame).

import geopandas as gpd
shapes = gpd.read_file("a_shapefile.shp")
list(shapes.columns.values)
[u'dip', u'dip_dir', u'cosa', u'sina', 'geometry']
# first features
shapes.head(3)

entrez la description de l'image ici

2) Fichiers de formes multiples: si vous souhaitez parcourir plusieurs fichiers de formes dans un dossier

Avec osgeo.ogr

for subdir, dirs, files in os.walk(rootdir):
     for file in files:
        if file.endswith(".shp"):
           source = ogr.Open(os.path.join(rootdir, file))
           layer = source.GetLayer()
           ldefn = layer.GetLayerDefn()
           schema = [ldefn.GetFieldDefn(n).name  for n in range(ldefn.GetFieldCount())]
           print schema

ou avec un générateur

def records(shapefile):  
    # generator 
    reader = ogr.Open(shapefile)
    layer = reader.GetLayer(0)
    for i in range(layer.GetFeatureCount()):
        feature = layer.GetFeature(i)
        yield json.loads(feature.ExportToJson())

for subdir, dirs, files in os.walk(rootdir):
    for file in files:
       if file.endswith(".shp"):
          layer = records(os.path.join(rootdir, file))
          print layer.next()['properties'].keys()

Avec Fiona

import fiona
for subdir, dirs, files in os.walk(rootdir):
   for file in files:
      if file.endswith(".shp"):
          layer = fiona.open(os.path.join(rootdir, file))
          print layer.schema['properties'].keys()

1
C'est une réponse extrêmement exhaustive!
Kersten

11

Utilisation:

from osgeo import ogr

ds = ogr.Open("file.shp")
lyr = ds.GetLayer()

field_names = [field.name for field in lyr.schema]
print(field_names)

Parfait. C'est tout ce qu'il faut
Ishan Tomar
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.