I'd like to replace this expression

arcpy.CalculateField_management(bufferFile, "Shape_Area", "float('!shape.area@squaremeters!')", "PYTHON")

with an arcpy.da.updatecursor. The reason for this is that i want to avoid the cryptic syntax of the command above to improve code readability.

Is this possible?

  • What does this line do btw? shape.area@squaremeters
    – R.K.
    Dec 4 '12 at 6:24
  • it refreshes the pre-defined Shape_Area field, and populates it with a value in square meters
    – lightxx
    Dec 4 '12 at 6:28

First you'll need to get the areas

bufferfile_with_areas = "bufferfilewithareas.shp" #or whichever path you want     
arcpy.CalculateAreas_stats(bufferfile, bufferfile_with_areas)

This would create a copy of your old file but with an F_AREA field. This field will contain the area values that you want to assign to the Shape_Area field.

rows = arcpy.UpdateCursor(bufferFile_with_areas)

for row in rows:
    row.Shape_Area = float(row.F_AREA) 
del row
del rows

The updateCursor will have to go through your attributes one row at a time and assign the value to the Shape_Area attribute. You will need an extra conversion step though, to convert the units from the one given by the arcpy.CalculateAreas_stats to square metres.

  • thanks for your answer. unfortunately i'm lacking the rep to upvote your post :(
    – lightxx
    Dec 4 '12 at 6:27
  • It's okay. Do you already have the table with the area values?
    – R.K.
    Dec 4 '12 at 6:27
  • yes. arcgis (at least 10.1) automatically adds a field called 'Shape_Area' when you run the buffer tool on a shape file. the problem is that the value of Shape_Area is the pre-buffer area and needs to be updated to reflect the new size. that's what the command in my first post does.
    – lightxx
    Dec 4 '12 at 6:35
  • 1
    You are on the right track - however, you can eliminate the step CalculateAreas and update the Shape_Area field with the Python expression you already have used in the field calculator - set the search cursor on your orig buffer file: row.Shape_Area = row.shape.area@squaremeters Dec 4 '12 at 13:32
  • @T.WayneWhitley Didn't know about that. Thanks! Will update my answer with you comment if you don't mind. :)
    – R.K.
    Dec 4 '12 at 13:37

My apologies for the delay, but thought I'd post this to help explain (and cover for) my last post. I did test this and confirmed the code below works, maybe faster than the field calculator. My apologies if I misled anyone with the use of the '@' token -- instead I used a spatial reference object with the update cursor to make the 'on the fly' conversion. The key line (see below) is setting the update cursor, essentially the 3rd parameter enables the unit conversion without the intermediate step, CalculateAreas_stats (or even without a further step with unit conversion), as I promised wasn't necessary (@ R.K. - sorry for not explaining better earlier):

Here's the critical line in the code: rows = arcpy.UpdateCursor(fc, '', objSR)

EDIT: One more thing, about the 'data access' module update cursor (arcpy.da.UpdateCursor), which is part of the original question -- I don't have 10.1 at this point, but the documentation shows the SR object is supported the same way "...can be specified with either a SpatialReference object or string equivalent." Looks like access to geometry has changed slightly, using the '@' token: SHAPE@AREA


import arcpy, os

# Target shapefile (in native state plane feet units):
fc = r'C:\Documents and Settings\whitley-wayne\Desktop\updatecursorShapeArea\New_ShapefileBuffer.shp'

# The state plane system projection file:
prjFilename = r'NAD 1983 HARN StatePlane Florida East FIPS 0901 (Meters).prj'

# The system subdirectory tree:
coordSysDir = r'Coordinate Systems\Projected Coordinate Systems\State Plane\NAD 1983 HARN (Meters)'

# ...getting the ArcGIS install directory and joining the above path- and file- names...
prjFilepath = os.path.join(os.path.join(arcpy.GetInstallInfo()['InstallDir'], coordSysDir), prjFilename)

# The spatial reference object (establishing a metric unit of measure):
objSR = arcpy.SpatialReference(prjFilepath)

# Opening an update cursor using the spatial reference object (in meters)...

# The shapefile native units are still feet.
# The update cursor will update the Shape_Area field using objSR for the units conversion to meters:
rows = arcpy.UpdateCursor(fc, '', objSR)
for row in rows:
               row.Shape_Area = row.shape.area

del row, rows
  • I find it interesting that this is faster than the field calculator for you. In my admittedly limited experience with search cursors, I've always found it to be way slower than using CalculateField_management(feature,field,!shape.area@squaremeters!) I'll have to try your code out. Mar 5 '13 at 19:59
  • As for comparative speeds of update cursor and field calculator, check this out
    – Barbarossa
    Aug 6 '13 at 15:07

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.