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 an integer raster for which I would like to build a raster attribute table using Python and GDAL. I can create a GDAL raster attribute table in Python as follows:

>>> rat = gdal.RasterAttributeTable()

This works fine, as we can see:

>>> rat
<osgeo.gdal.RasterAttributeTable; proxy of <Swig Object of type 'GDALRasterAttributeTableShadow *' at 0x0000000002A53D50> >

The table thus created has no rows or columns:

>>> rat.GetRowCount()
0
>>> rat.GetColumnCount()
0

I create a column called "Value" to store the unique values in the raster:

>>> rat.CreateColumn("Value", gdalconst.GFT_Integer, gdalconst.GFU_MinMax)
0

This is fine, and the column count is updated:

>>> rat.GetColumnCount()
1

Now I have to add values (records) to the column for it to be of any use. I can get a list of unique values from the raster's band like so:

>>> data = band.ReadAsArray(0, 0, dataset.RasterXSize, dataset.RasterYSize)
>>> vals = list(numpy.unique(data))
>>> vals
[3, 7, 8, 10, 11, 12, 13, 14, 17, 18, 20, 22, 23, 25, 27, 28, 41, 45, 52, 56]

What I would like to do is create a for loop to loop through vals and populate the column in the attribute table. I thought I could do something like this:

>>> for i in range(len(vals)):
        rat.SetValueAsInt(i, 0, vals[i])

...where i is the row (record), 0 is the field index and vals[i] is the integer value I want to insert. But it causes an error:

Traceback (most recent call last):
  File "<pyshell#32>", line 2, in <module>
    rat.SetValueAsInt(i, 0, vals[i])
  File "C:\Python27\lib\site-packages\osgeo\gdal.py", line 1139, in SetValueAsInt
    return _gdal.RasterAttributeTable_SetValueAsInt(self, *args)
TypeError: in method 'RasterAttributeTable_SetValueAsInt', argument 4 of type 'int'

The error is caused because I use vals[i] in the call to SetValueAsInt() rather than using an integer directly. For example, rat.SetValueAsInt(0, 0, 0) works fine, but is useless for populating the column if I just want to loop over the list of unique values.

Is this a known issue? Google has so far not been very useful. What can I do to get around this problem?

share|improve this question
add comment

2 Answers

up vote 7 down vote accepted

The SetValueAsInt method is expecting a python int type, not a numpy type.

>>> print type(vals[0])
<type 'numpy.uint16'>

The following works:

rat.SetValueAsInt(i, 0, int(vals[i]))
share|improve this answer
add comment

If you use vals = numpy.unique(data).tolist() instead it will automatically convert each value to a python int type.

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.