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).

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? 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)?
    – AF2k15
    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. 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" )
1
  • Thanks Michael, I'm back on track! I literally don't know what I'd do without you :)
    – AF2k15
    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).

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.
    – AF2k15
    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
    – AF2k15
    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. 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.
    – AF2k15
    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). Feb 16, 2015 at 4:16

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.