Uzyskaj nazwy pól plików kształtów za pomocą GDAL

15

Używam GDAL w Pythonie do importowania pliku shapefile. Chcę poznać nazwy pól dla pliku, moja obecna droga to:

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

Ale w ten sposób otrzymuję funkcję dla pierwszej warstwy. Czy to znaczy, że różne warstwy mogą mieć różne funkcje?

Jeśli nie, to czy można uzyskać nazwy pól od razu, zamiast wchodzić w tak głębokie? Jeśli tak, czy istnieje łatwiejszy sposób na uzyskanie nazw pól?

użytkownik3716774
źródło
Shapefile ma zawsze tylko jedną warstwę. Uważam również, że każda funkcja ma te same atrybuty, więc wystarczy sprawdzić tylko pierwszą funkcję.
user30184,

Odpowiedzi:

24

1) indywidualny plik kształtów: jak w komentarzu, plik kształtów ma tylko jedną warstwę. Jeśli chcesz tylko nazwy pól

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

Możesz użyć formatu GeoJSON z generatorem Pythona ( 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']

Wprowadza to Fiona (kolejne opakowanie OGR, Python 2.7.xi 3.x). Wszystkie wyniki są słownikami w języku 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)])}

I GeoPandas (Fiona + pandy , Python 2.7.x i 3.x). Wynikiem jest 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)

wprowadź opis zdjęcia tutaj

2) Wiele plików kształtów: jeśli chcesz iterować przez wiele plików kształtów w folderze

Z 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

lub z generatorem

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

Z Fioną

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
źródło
1
To wyjątkowo wyczerpująca odpowiedź!
Kersten,
11

Posługiwać się:

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
źródło
Doskonały. To wszystko jest wymagane
Ishan Tomar