Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I have a Python script that adds an attribute field to a Shapefile if doesn't exist. This is easy to do with ArcGIS (graphically or via Python), but I'm looking for something that doesn't depend on ArcGIS.

I tried this unsuccessfully with OGR, since my Shapefile contains features.

I've looked at pyshp, but similarly there is no way to modify the schema after it has been created. I haven't had a try with shapefile (for Python), but I don't see this feature advertised. I also can't see how this can be done by tinkering with the DBF file via dbfpy.

Does anyone have any ideas?


Solved

I found a solution using OGR and thanks to help from a previous question. Here is a complete example:

from osgeo import ogr

# Open a Shapefile, and get field names
source = ogr.Open('my.shp', 1)
layer = source.GetLayer()
layer_defn = layer.GetLayerDefn()
field_names = [layer_defn.GetFieldDefn(i).GetName() for i in range(layer_defn.GetFieldCount())]
print len(field_names), 'MYFLD' in field_names

# Add a new field
new_field = ogr.FieldDefn('MYFLD', ogr.OFTInteger)
layer.CreateField(new_field)

# Close the Shapefile
source = None

My problem was that I used layer_defn.AddFieldDefn(new_field) rather than layer.CreateField(new_field). Many thanks to the help, and sorry for not throughly checking for the similar other question.

share|improve this question
    
Would it be acceptable to clone the existing shapefile structure, add a new column, and then populate it based on the original shapefile? –  DavidF Mar 18 '11 at 13:04
    
possible duplicate of Adding custom Feature attributes to ESRI Shapefile with Python –  whuber Mar 18 '11 at 15:24
    
This question should be closed as a duplicate of gis.stackexchange.com/q/3623/664 . –  whuber Mar 18 '11 at 15:24
    
Yes, essentially the same. I looked, but didn't see it. –  Mike T Mar 18 '11 at 22:12
    
Thanks for posting your answer, it helped! –  rengis Jul 12 '11 at 18:20
add comment

4 Answers

up vote 5 down vote accepted

you should have a look on these questions since it has been answered already : Adding custom Feature attributes to ESRI Shapefile with Python

http://stackoverflow.com/questions/4215658/adding-custom-feature-attributes-to-esri-shapefile-with-python

If you want as result, only one shapefile, just delete your input files at the end of your script.

share|improve this answer
    
Which is also similar to gis.stackexchange.com/questions/3623/… Thanks for digging that up –  Mike T Mar 18 '11 at 22:13
add comment

DBFpy should work for this. Have you seen then example on this page:

http://dbfpy.sourceforge.net/

Make sure the shapefile isn't being edited by any other application including ArcGIS at the time as this may cause issues via locking.

share|improve this answer
    
I don't think this works if you already have data in the DBF file. I had looked at it before, but I get an error: "At least one record was added, structure can't be changed". Do you have any specific example in mind? –  Mike T Mar 18 '11 at 11:18
    
Ah I remember now yes as Sasa said the creation of a new DBF would be required. Copy the schema (as in fields etc.) across then make your additions, then copy the records across. The "great" DBF... :( –  Rob Clark Mar 18 '11 at 13:46
    
@Mike How was a record added when all you want to do is add a field?? Adding a record is an error because it ruins the connection between the attributes and the shapes. Adding a field does no harm at all. Any library that can edit dbf files will do the job properly. –  whuber Mar 18 '11 at 15:23
    
@whuber: That is their error message. Open an existing dbf that has data and see: from dbfpy import dbf; db = dbf.Dbf('my.dbf'); db.addField(("FOO", "C", 15)) –  Mike T Mar 18 '11 at 21:52
    
@Mike Thanks for clarifying the situation. That sounds like the result of an unnecessary limitation in dbfpy :-(. I can guess why: adding a field in a non-empty database requires all the records to be physically read, expanded, and written back out again. A good solution is to find a different dBase library or use other software ;-). –  whuber Mar 18 '11 at 22:08
add comment

Thanks to a rather brain-dead format called DBF, adding fields to shapefiles with existing attribute data isn't possible without rewriting or adding padding to the DBF. I don't know of a ready-made solution, but what I would do is write a script to create a new shapefile based on an existing one and add the extra field(s) to the new shapefile. Then copy the geometry/attribute data from old to new shapefile. And as a final step, remove the old shapefile, and rename the new one. All of this is fairly easily accomplished using OGR python bindings.

Alternately, you can use dbfpy to do the above with just the DBF file. Order of steps remains the same:

  1. Create a new DBF with identical structure to original
  2. Create new attribute fields in the new DBF
  3. Copy data from original DBF to new DBF
  4. Remove old DBF, rename new DBF to old DBF

You don't need to make any changes to the shapefile (.shp) itself or any of the other files, as they do not reference attribute information contained in the DBF. You do however need to keep the order of records exactly the same in the old and the new DBF.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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