Select to view content in your preferred language

Update Cursor for Rasters?

1591
6
02-24-2012 08:01 AM
RichardThurau
Deactivated User
Hi,
I'm trying to use python to add a field and add some text for an attribute class. Funny thing is (actually not so funny) update cursor returns an error and destroys my raster!

import arcpy
#import os
from arcpy.sa import *
from arcpy import env
arcpy.CheckOutExtension("Spatial")
arcpy.env.overwriteOutput = True

WScom4_rc = "X:\\DATA\\watershed_100mbuf_lc_8class.img"

arcpy.AddField_management(WScom4_rc, "Class_Name", "TEXT")
rows = arcpy.UpdateCursor(WScom4_rc)
for row in rows:
    if row.Value == 1:
        row.Class_Name = "Forest"
        rows.updateRow(row)
    if row.Value == 2:
        row.Class_Name = "Developed"    
        rows.updateRow(row)
    if row.Value == 3:
        row.Class_Name = "Fields/Pastures"
        rows.updateRow(row)
    if row.Value == 4:
        row.Class_Name = "Wetlands"    
        rows.updateRow(row)
    if row.Value == 5:
        row.Class_Name = "Water"
        rows.updateRow(row)
    if row.Value == 6:
        row.Class_Name = "Barren/Soil"    
        rows.updateRow(row)
    if row.Value == 7:
        row.Class_Name = "Open Space"
        rows.updateRow(row)
    if row.Value == 8:
        row.Class_Name = "Deforested"    
        rows.updateRow(row)
    if row.Value == 9:
        row.Class_Name = "Ice/Snow/Shadow (unclassified)"    
        rows.updateRow(row)


Here is the error code:
Traceback (most recent call last):
  File "X:\DATA\FloodRisk2_Canada\02_Source_Data\2_Working_Source_Data\Goulds_working\FloodVul_process_script1_goulds.py", line 74, in <module>
    row.Class_Name = "Forest"
  File "C:\Program Files (x86)\ArcGIS\Desktop10.0\arcpy\arcpy\arcobjects\_base.py", line 35, in __setattr__
    return setattr(self._arc_object, attr, ao)
RuntimeError: ERROR 999999: Error executing function.

The input raster has a normal raster attribute table: Rowid, value, count.
The output is an empty raster where the attribute table contains Rowid, value, count, and Class, but no rows (no data).

Can update cursor be used for editing raster attributes? If so, How?

Thanks!

Rich
Tags (2)
0 Kudos
6 Replies
JakeSkinner
Esri Esteemed Contributor
Hi Rich,

It looks like you are specifying the incorrect field name.  You created the new field called 'Class', but you are trying to update a field called 'Class_Name'.  Change all 'row.Class_Name' objects to 'row.Class' and your code should work.
0 Kudos
RichardThurau
Deactivated User
Jake,
Thanks for taking a look.

While that is the source of the error, it is not the source of the problem. Changing the field name was something I was messing with to try and resolve.
I edited the code in my original post.

The main issue still remains:
When I push the above code to Update Cursor, I get an empty raster output. The code runs, with no errors, but an empty dataset is returned.

It is very bad when stuff does that to data.

Anyone out there successfully use Update Cursor to modify Raster attributes?
How about Calculate Field (which I have not tried)?

Thanks

RT
0 Kudos
curtvprice
MVP Alum
My 2 cents:

Raster attribute tables are very tricky, as they are implemented differently for different image types. For example, with raw data formats like .bil, they are stored in an .aux/.aux.xml file. With .tiffs, the raster table is an RGB colormap table stored in the image header. ERDAS .img files look like more advanced tables, but I'm not sure you can successfully modify an .img's table because it is stored in the image itself. With grids, you may have better luck, as the table is a good old INFO table stored in the info folder parallel to the grid.

In general, I've found it best practice to only use the VALUE and COUNT fields and handle any other table information by joining to a separate lookup table. This generally makes more sense because most raster tools drop all variables from the output except VALUE and COUNT.

Your approach looks like it could be much more efficiently done  (and perhaps with more success with non-grid formats, but I don't know...)  by creating a lookup table in the in_memory workspace, populating it with a cursor, and then doing a Add Field / Add join / Calculate Field, or Join Field to copy the data over. But IMHO the separate ancillary data table is the most reliable path.
0 Kudos
JakeSkinner
Esri Esteemed Contributor
This could be something specific with the raster you are using.  I tested with a .IMG using ArcGIS 10 SP3 and everything worked as it should.  I've attached the .IMG file.  See if you are able to reproduce the same issue with the attached IMG.
0 Kudos
RichardThurau
Deactivated User
Thanks Curtis and Jake for your input.
First of all, it is very important for this work to remain in raster format: raster processing is a lot faster, and raster is required for further analysis steps.

Second, IMG is over geodatabase grid because it is interchangeable between ESRI and Erdas.

Having said that:
Jake, I ran my script on the img you sent, and it did the same thing: erased the data, spit out an empty attribute table. Did you run the same code I posted?

Can you post your code? It would be awesome to get this working for IMGs.
I am also running 10, sp3. It's on a 64-bit win7 machine but that shouldn't matter.

I ran the code on a geodatabase grid, and it worked the way it's supposed to. I don't like being tied to the geodatabase but for now I think it will do.

Thanks again for your input.

Rich
0 Kudos
JakeSkinner
Esri Esteemed Contributor
Hi Rich,

I ran the same code that you posted.  The only difference that I can see is that my raster is on my local disk.  Try copying the IMG to your local C:\ drive and see if you can reproduce the same issue.
0 Kudos