14

I use GDAL in Python for importing shapefile. I want to know the field names for the file, my current way is:

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

But this way, I am getting the feature for the first layer. Does it mean it is possible that different layers can have different features?

If not, is it possible to get the field names at once, instead of getting into this deep? If yes, is there any easier way of getting the field names?

  • Shapefile has always only one layer. I also believe that each feature has the same attributes so it is enough to check just the first feature. – user30184 Dec 9 '16 at 5:37
23

1) individual shapefile: as in the comment, a shapefile has only one layer. If you want only the names of the fields

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

You can use the GeoJSON format with a Python generator (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']

This introduces Fiona (another Python wrapper of OGR, Python 2.7.x and 3.x). All results are Python dictionaries (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)])}

And GeoPandas (Fiona + pandas, Python 2.7.x and 3.x). The result is a 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)

enter image description here

2) Multiple shapefiles: if you want to iterate through multiple shapefiles in a folder

With 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

or with a 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()

With 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
    This is an excellently exhaustive answer! – Kersten Dec 12 '16 at 9:09
11

Use:

from osgeo import ogr

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

field_names = [field.name for field in lyr.schema]
print(field_names)
  • Perfect. That is all is required – Ishan Tomar Jun 13 '18 at 9:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.