19

I am seeking a way to take an existing Shapefile that has a Feature set of 200 countries. Each country Feature has an attribute of "NAME." My objective is to create a Python script that adds an arbitrary (for now) additional attribute, say, "POPULATION".

Of course I have the OSGeo and GeoDjango modules installed. I'm as far as:

 from osgeo import ogr

    infile = ogr.Open('sample.shp', 1) #'sample.shp' is a pre-existing ESRI shapefile described above
    inlyr = ogr.GetLayerByIndex(0)

Am I missing an OGR function that will allow me to insert Feature attribute fields into an existing Shapefile?

PolyGeo
  • 65,136
  • 29
  • 109
  • 338
mattdeboard
  • 383
  • 1
  • 2
  • 7

2 Answers2

17

Is it possible to add a field to an existing shapefile using Python OGR..

from osgeo import ogr
driver = ogr.GetDriverByName('ESRI Shapefile')
dataSource = driver.Open(“c:/test/Test2.shp”, 1) #1 is read/write

#define floating point field named DistFld and 16-character string field named Name:
fldDef = ogr.FieldDefn('DistFld', ogr.OFTReal)
fldDef2 = ogr.FieldDefn('Name', ogr.OFTString)
fldDef2.SetWidth(16) #16 char string width

#get layer and add the 2 fields:
layer = dataSource.GetLayer()
layer.CreateField(fldDef)
layer.CreateField(fldDef2)
Dave
  • 171
  • 1
  • 3
  • 6
    Thanks. To populate and write the data, I added these: for feat in layer: feat.SetField('Name','myname') layer.SetFeature(feat) dataSource=None – Dave X Nov 11 '13 at 22:10
13

I believe the Assemble TIGER Polygons sample has what you're looking for:

# Open the datasource to operate on.

ds = ogr.Open( infile, update = 0 )

poly_layer = ds.GetLayerByName( 'Polygon' )

#############################################################################
#   Create output file for the composed polygons.

nad83 = osr.SpatialReference()
nad83.SetFromUserInput('NAD83')

shp_driver = ogr.GetDriverByName( 'ESRI Shapefile' )
shp_driver.DeleteDataSource( outfile )

shp_ds = shp_driver.CreateDataSource( outfile )

shp_layer = shp_ds.CreateLayer( 'out', geom_type = ogr.wkbPolygon,
                                srs = nad83 )

src_defn = poly_layer.GetLayerDefn()
poly_field_count = src_defn.GetFieldCount()

for fld_index in range(poly_field_count):
    src_fd = src_defn.GetFieldDefn( fld_index )

    fd = ogr.FieldDefn( src_fd.GetName(), src_fd.GetType() )
    fd.SetWidth( src_fd.GetWidth() )
    fd.SetPrecision( src_fd.GetPrecision() )
    shp_layer.CreateField( fd )
Derek Swingley
  • 14,462
  • 2
  • 44
  • 63
  • Thanks, is this just something you were familiar with beforehand or did you find it after searching? – mattdeboard Nov 18 '10 at 20:06
  • 1
    NP, I knew of the samples but looked through a few to find this specific piece. – Derek Swingley Nov 18 '10 at 20:45
  • Ah ok, great. I am going to wait until I'm at home and can try to implement this before I mark this as answered, but it's looking good. – mattdeboard Nov 18 '10 at 20:52
  • 1
    The example above creates a new shapefile. Then you must transfer all the other fields and geometry from existing to new file. Do you need an example that adds a field to an existing shapefile? – klewis Feb 21 '11 at 17:10
  • @klewis- you might want to ask this as a question on the original question. I was notified of your response but I don't think the OP will be. – Derek Swingley Feb 21 '11 at 19:11