2

I'm trying to iterate over each field in a shapefile. Then iterate over each record in that field.

First I build a list of all the fields, then iterate through that list. While I'm going through the list, I loop through all the features via feat = feature.GetField(x) where x is the current field.

This works for the first field. It prints the first field, then all of its records. Then it proceeds to just loop through the rest of the fields, not the records. It's like it just runs the records for loop once. I have no idea why. I think it should work.

from osgeo import ogr

shapefile = r"E:\metadata_2\data\test.shp"
driver = ogr.GetDriverByName("ESRI Shapefile")
dataSource = driver.Open(shapefile, 0)
layer = dataSource.GetLayer()
layerDefinition = layer.GetLayerDefn()

layer_list = []

def getfields():

    for i in range(layerDefinition.GetFieldCount()):
        layer_name = layerDefinition.GetFieldDefn(i).GetName()
        layer_list.append(layer_name)

    print layer_list

    for x in layer_list:
        print 'This is the layer {}'.format(x)
        for feature in layer:
        feat = feature.GetField(x)
        print feat

getfields()
  • Your feat = feature.Get.... and print feat statements should be indented one more to the right. – artwork21 Dec 1 '16 at 15:14
5

The reason for this behavior is that ogr reads the features of layer sequentially and updates the "read position" each time. After reading through layer once, the "read position" is at the end of the file/record. Attempting to read features again in the next loop for the next field will not produce any feature records. You need to reset the read position to the start of the records after each field is read.

from osgeo import ogr

shapefile = r"E:\metadata_2\data\test.shp"
driver = ogr.GetDriverByName("ESRI Shapefile")
dataSource = driver.Open(shapefile, 0)
layer = dataSource.GetLayer()
layerDefinition = layer.GetLayerDefn()

layer_list = []

def getfields():
    for i in range(layerDefinition.GetFieldCount()):
        layer_name = layerDefinition.GetFieldDefn(i).GetName()
        layer_list.append(layer_name)

    print layer_list

    for x in layer_list:
        print 'This is the layer {}'.format(x)
        for feature in layer:
            feat = feature.GetField(x)
            print feat
        layer.ResetReading()  # reset the read position to the start

# main
getfields()
  • That worked! Thank you for the explanation as well. – fpolig01 Dec 1 '16 at 15:21

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.