1

I am wanting to set an existing field called RasterID to the name of the raster for which the attribute table belongs to, but for a batch of rasters. Is there a way to do this with my current code structure and by setting 'expression' equal to the raster name? If I simply set expression = desc.baseName, I get an error.

This is how I am trying to implement arcpy.Describe():

import os,arcpy,glob
from arcpy import env
arcpy.env.workspace = r"C:\VMshared\small_example_valley3\SnowDepth4"
#arcpy.env.overwriteOutput = True
fieldName = "RasterID"
for rasterFile in arcpy.ListRasters("*.tif"):
 desc = arcpy.Describe(rasterFile)
 print "Base Name: " + desc.baseName 
 expression = desc.baseName
 print expression
 arcpy.CalculateField_management(rasterFile, fieldName, expression, "PYTHON_9.3") #something wrong with this line?
print "done"

Base Name: snowdepthN0001 snowdepthN0001 Runtime error Traceback (most recent call last): File "", line 12, in
File "c:\program files (x86)\arcgis\desktop10.1\arcpy\arcpy\management.py", line 3128, in CalculateField raise e ExecuteError: ERROR 000539: Error running expression: snowdepthN0001 Traceback (most recent call last): File "", line 1, in NameError: name 'snowdepthN0001' is not defined Failed to execute (CalculateField).

PolyGeo
65.5k29 gold badges115 silver badges349 bronze badges
asked Feb 15, 2015 at 23:21
3
  • 1
    You will need to quote your raster file or it's looking for a field called that. "\"" + expression + "\"" is the quoted string. Note that this code will populate all the fields with the same rasterID, is this what you want? Commented Feb 15, 2015 at 23:28
  • @Michael Miles-Stimson As in arcpy.Describe("rasterFile")?--I (get erros for this) I'm not sure what the meaning of quote the raster file is. Also, do I need arcpy.GetParameterAsText(0)? Commented Feb 16, 2015 at 17:11
  • See answer. arcpy.GetParameterAsText (or sys.argv) is unnecessary as no input is required, all of the information is obtained from the current map document except the field names which should be as written... no need for input. Commented Feb 16, 2015 at 22:24

2 Answers 2

2

I can see that multiple comments aren't being understood. This is what I meant:

import os,arcpy
from arcpy import env
mxd = arcpy.mapping.MapDocument("CURRENT")
#arcpy.env.overwriteOutput = True
fieldName = "RasterID"
RowsField = "unknown" # the field (numeric) for the number of rows
ColsField = "unknown" # the field (numeric) for the number of columns
for lyr in arcpy.mapping.ListLayers(mxd):
 desc = arcpy.Describe(lyr)
 expression = desc.baseName
 desc = arcpy.Describe(desc.catalogPath) # describe the data that the layer points to
 arcpy.AddMessage("Base Name: " + expression )
 arcpy.AddMessage("Rows: " + str(desc.height) + ", Cols:" + str(desc.width))
 arcpy.CalculateField_management(lyr, fieldName, "\"" + expression + "\"", "PYTHON_9.3")
 arcpy.CalculateField_management(lyr, RowsField, desc.height,"PYTHON_9.3")
 arcpy.CalculateField_management(lyr, ColsField, desc.width,"PYTHON_9.3")
arcpy.AddMessage("done")

When I say that you need to quote the value it is for the field calculator to know that you want to calculate a constant string value expression and not a field called expression, to do this you need to surround the expression by quote marks thus: "\"" + expression + "\""; in python (and many other languages) if you want to include a quote mark in a string you need to escape it, this allows characters that you wouldn't normally be able to put into the string like \" (quote), \n (new line) and \t (tab). Because the \ character is used to escape if you want one in a string you need to put two \\ which python interprets as ,円 for example a path name : "C:\\some\\folder" is interpreted as C:\some\folder.

This only applies for string fields, all other fields that you can calculate (short, long, double etc..) do not need to be quoted.

With some error checking:

import os,arcpy
from arcpy import env
mxd = arcpy.mapping.MapDocument("CURRENT")
fieldName = "RasterID"
RowsField = "unknown" # the field (numeric) for the number of rows
ColsField = "unknown" # the field (numeric) for the number of columns
for lyr in arcpy.mapping.ListLayers(mxd):
 desc = arcpy.Describe(lyr) # describe the layer
 expression = desc.baseName
 arcpy.AddMessage( "Base Name: " + expression )
 desc = arcpy.Describe(desc.catalogPath) # describe the data that the layer points to
 gotRowsCols = True # assume true unless they can't be retrieved
 try:
 arcpy.AddMessage("Rows: " + str(desc.height) + ", Cols:" + str(desc.width))
 except:
 arcpy.AddWarning("Cannot retrieve rows-cols property, layer may not be a raster")
 gotRowsCols = False # unable to get the rows-cols from the layer
 # look for the RasterID field and if it exists try to calculate the name of the raster
 # and then rows and columns if those fields are found
 field = arcpy.ListFields(lyr,fieldName)
 if field:
 arcpy.CalculateField_management(lyr, fieldName, "\"" + expression + "\"", "PYTHON_9.3")
 # if the rows and columns values can be retrieved then try find the fields and calc
 if gotRowsCols:
 # try to find the RowsField and if it exists then calc the height of the raster
 field = arcpy.ListFields(lyr,RowsField)
 if field:
 arcpy.CalculateField_management(lyr, RowsField, desc.height,"PYTHON_9.3")
 # try to find the ColsField and if it exists then calc the width of the raster
 field = arcpy.ListFields(lyr,ColsField)
 if field:
 arcpy.CalculateField_management(lyr, ColsField, desc.width,"PYTHON_9.3")
 else:
 # field not found in this layer, issue a warning and move on.
 arcpy.AddWarning("Field not found " + fieldName)
arcpy.AddMessage( "done" )
answered Feb 16, 2015 at 22:21
1
  • Thanks Michael, I'm back on track! I literally don't know what I'd do without you :) Commented Feb 16, 2015 at 22:57
1

As @Michael Miles-Stimson has commented your calculate field method will overwrite all row values each loop through the raster list method. So, the table will only have one raster name for each record. In addition, it is unclear from your question if the update table has an equal number of rows for rasters that exist within the directory.

If you are simply wanting to add new rows to a table I would recommend using an insert cursor. If you are wanting to update an existing table/rows you could use a update cursor (make sure you put the expression statement within the update cursor loop so each row will get a different raster name).

You could use the calculate field method, but you would have to first make the update table a feature layer and perform a select by attribute on one row at a time before the calculate field statement (...iterating selected row and calculate field.....iterating selected row and calculating field....etc).

answered Feb 16, 2015 at 2:23
8
  • @Michael Miles-Stimson Thanks for your responses, they are much appreciated. To clarify, I was envisioning that each record of the rasterID field would be filled with the raster's actual name for that particular raster. Then for the next raster file each record for the rasterID field set to that raster's name. My purposes for wanting this is so I can join a timestamp table based on the new rasterID fields. So I'm just wanting each rasterID field to be filled with its raster's name. I will try your suggestions. Commented Feb 16, 2015 at 3:05
  • Also, I forgot to respond to your question about the number of rows. Each raster file in the directory has a variable amount of rows for its existing rasterID field (which have already been added, but are blank), so in other words, they don't have an equal number of rows Commented Feb 16, 2015 at 3:25
  • Have you considered doing this in python? The rows/columns are available via the Describe method, you could do all 3 at once. Commented Feb 16, 2015 at 3:50
  • @Michael Miles-Stimson Is this the one? "Base Name: " + desc.baseName I'll try to figure out how to implement this. It sounds right. Commented Feb 16, 2015 at 4:08
  • resources.arcgis.com/en/help/main/10.1/index.html#/… Being a raster the describe object has all the common properties of Dataset, Raster and Band... d = arcpy.Desribe(Raster) then cols = d.width and rows = d.height the baseName and catalogPath are givens (that's what you supply to the describe to get the object). Commented Feb 16, 2015 at 4:16

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.