0

Editing my previous question which asked the best way to buffer a point shapefile in python to add more detail and clarity to what I'm looking for.

I have found a method here to iterate through an input point feature class, buffer by a distance and write to an output polygon feature class:

def create_bufferShp_fromPointShp(inShpPath, bufferSize):

    buffShpPath = inShpPath.replace('.shp', '_buffer-{}m.shp'.format(bufferSize))

    inputds = ogr.Open(inShpPath)
    inputlyr = inputds.GetLayer()

    shpdriver = ogr.GetDriverByName('ESRI Shapefile')
    if os.path.exists(buffShpPath):
        shpdriver.DeleteDataSource(buffShpPath)
    outputBufferds = shpdriver.CreateDataSource(buffShpPath)
    bufferlyr = outputBufferds.CreateLayer(buffShpPath, geom_type=ogr.wkbPolygon)
    featureDefn = bufferlyr.GetLayerDefn()

    for feature in inputlyr:
        ingeom = feature.GetGeometryRef()
        geomBuffer = ingeom.Buffer(bufferSize)

        outFeature = ogr.Feature(featureDefn)
        outFeature.SetGeometry(geomBuffer)
        bufferlyr.CreateFeature(outFeature)
        outFeature = None

    # Copy the input .prj file
    from shutil import copyfile
    copyfile(inShpPath.replace('.shp', '.prj'), buffShpPath.replace('.shp', '.prj'))

    return buffShpPath

The resulting polygon feature class is exactly what I'm looking for, but I would like to carry over the attributes from the input feature class to the output. These fields may change, so I am looking for an automated way. I added this portion to before the for loop:

    # Try to create new fields in the output shp
    for i in range(inputlyr.GetLayerDefn().GetFieldCount()):
        bufferlyr.CreateField(inputlyr.GetLayerDefn().GetFieldDefn(i))

This creates the fields, but I am unsure (outside of hardcoding the fields with outFeature.SetField()) of the best way to copy the input attributes of a feature to the output feature class.

1

1 Answer 1

2

This worked for me:

def create_bufferShp_fromPointShp(inShpPath, bufferSize):

    buffShpPath = inShpPath.replace('.shp', '_buffer-{}m.shp'.format(bufferSize))

    print "\nCreating buffered shapefile..."

    inputds = ogr.Open(inShpPath)
    inputlyr = inputds.GetLayer()

    shpdriver = ogr.GetDriverByName('ESRI Shapefile')
    if os.path.exists(buffShpPath):
        shpdriver.DeleteDataSource(buffShpPath)
    outputBufferds = shpdriver.CreateDataSource(buffShpPath)
    bufferlyr = outputBufferds.CreateLayer(buffShpPath, geom_type=ogr.wkbPolygon)
    featureDefn = bufferlyr.GetLayerDefn()

    # Create new fields in the output shp and get a list of field names for feature creation
    fieldNames = []
    for i in range(inputlyr.GetLayerDefn().GetFieldCount()):
        fieldDefn = inputlyr.GetLayerDefn().GetFieldDefn(i)
        bufferlyr.CreateField(fieldDefn)
        fieldNames.append(fieldDefn.name)

    for feature in inputlyr:
        ingeom = feature.GetGeometryRef()
        fieldVals = [] # make list of field values for feature
        for f in fieldNames: fieldVals.append(feature.GetField(f))

        outFeature = ogr.Feature(featureDefn)
        geomBuffer = ingeom.Buffer(bufferSize)
        outFeature.SetGeometry(geomBuffer)
        for v, val in enumerate(fieldVals): # Set output feature attributes
            outFeature.SetField(fieldNames[v], val)
        bufferlyr.CreateFeature(outFeature)

        outFeature = None

    # Copy the input .prj file
    from shutil import copyfile
    copyfile(inShpPath.replace('.shp', '.prj'), buffShpPath.replace('.shp', '.prj'))


    return buffShpPath

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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