Mit GDAL Feldnamen von Shapefiles abrufen

15

Ich benutze GDAL in Python zum Importieren von Shapefile. Ich möchte die Feldnamen für die Datei kennen. Mein aktueller Weg ist:

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

Auf diese Weise erhalte ich jedoch das Feature für die erste Ebene. Bedeutet das, dass verschiedene Ebenen unterschiedliche Merkmale haben können?

Wenn nicht, ist es möglich, die Feldnamen sofort abzurufen, anstatt in diese Tiefe zu gelangen? Wenn ja, gibt es eine einfachere Möglichkeit, die Feldnamen zu ermitteln?

user3716774
quelle
Shapefile hat immer nur eine Ebene. Ich glaube auch, dass jedes Feature die gleichen Attribute hat, so dass es ausreicht, nur das erste Feature zu überprüfen.
user30184

Antworten:

24

1) individuelles Shapefile: Wie im Kommentar hat ein Shapefile nur eine Ebene. Wenn Sie nur die Namen der Felder wollen

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']

Sie können das GeoJSON-Format mit einem Python-Generator ( ogr_geointerface.py ) verwenden.

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']

Dies führt Fiona ein (ein weiterer Python-Wrapper von OGR, Python 2.7.x und 3.x). Alle Ergebnisse sind Python-Wörterbücher (GeoJSON-Format).

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)])}

Und GeoPandas (Fiona + Pandas , Python 2.7.x und 3.x). Das Ergebnis ist ein 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)

Bildbeschreibung hier eingeben

2) Mehrere Shapefiles: Wenn Sie mehrere Shapefiles in einem Ordner durchlaufen möchten

Mit 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

oder mit einem Generator

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()

Mit 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()
Gen
quelle
1
Dies ist eine sehr ausführliche Antwort!
Kersten
11

Verwenden:

from osgeo import ogr

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

field_names = [field.name for field in lyr.schema]
print(field_names)
Marcelo Villa
quelle
Perfekt. Das ist alles, was erforderlich ist
Ishan Tomar