12

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?

11

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

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

The following works:

rat.SetValueAsInt(i, 0, int(vals[i]))
3

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

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.