2

I have a binary ArcGRID raster (AIG/Arc/Info Binary Grid) with an attribute table. I would like to get only this attribute table but gdalinfo outputs also projection information and bounds and then wanted GDALRasterAttributeTable XML part:

$ gdalinfo us_120fbfm13 -nogcp -nomd -noct filename
Driver: AIG/Arc/Info Binary Grid
...
Coordinate System is:
PROJCS["unnamed",
...
Center      ( 1540680.000, 1553400.000) ( 78d42'42.88"W, 35d46' 8.50"N)
Band 1 Block=256x4 Type=Byte, ColorInterp=Undefined
  Min=1.000 Max=99.000 
  NoData Value=255
<GDALRasterAttributeTable>
...

How to show only raster attribut table using GDAL command line tools gdalinfo or perhaps gdal_translate?

Additional question which might be separate but might be also answered together with this is whether there is a possibility to get the attribute table in format such as CSV and not XML.

I'm on Linux, so I can actually do something like:

gdalinfo us_120fbfm13 -nogcp -nomd -noct -nofl | grep "<.*>"

but I would rather use some more general and possibly cross-platform solution.

6

Unless you use os/shell specific operations i.e. grep etc... there's no way that I know of to do this from the command line with gdalinfo.

A python alternative is to use the GetDefaultRAT() method and output to XML (which is what gdalinfo does):

import sys
from osgeo import gdal
import xml.etree.ElementTree as et #I much prefer the lxml library
                                   #but it's 3rd party and must be installed

def toxml(rat):
    #partial port of Serialize() from svn.osgeo.org/gdal/trunk/gdal/gcore/gdal_rat.cpp

    rattree=et.Element('GDALRasterAttributeTable')

    coltypes=[]

    #Define each column.
    icolcount=rat.GetColumnCount()
    for icol in range(icolcount):
        field=et.SubElement(rattree,'FieldDefn', {'index':str(icol)})
        fname=et.SubElement(field,'Name')
        ftype=et.SubElement(field,'Type')
        fusage=et.SubElement(field,'Usage')

        itype=rat.GetTypeOfCol(icol)

        fname.text=rat.GetNameOfCol(icol)
        ftype.text=str(rat.GetTypeOfCol(icol))
        fusage.text=str(rat.GetUsageOfCol(icol))

        if itype==gdal.GFT_Integer:
            coltypes.append(['%s', rat.GetValueAsInt])
        elif itype==gdal.GFT_Real:
            coltypes.append(['%.16g', rat.GetValueAsDouble])
        else:
            coltypes.append(['%s', rat.GetValueAsString])

    #Write out each row.
    irowcount = rat.GetRowCount()
    for irow in range(irowcount):
        row=et.SubElement(rattree,'Row', {'index':str(irow)})
        for icol in range(icolcount):
            rowcol=et.SubElement(row,'F')
            itype=rat.GetTypeOfCol(icol)
            if itype==gdal.GFT_Integer:
                rowcol.text='%s'%rat.GetValueAsInt(irow,icol)
            elif itype==gdal.GFT_Real:
                rowcol.text='%.16g'%rat.GetValueAsDouble(irow,icol)
            else:
                rowcol.text='%s'%rat.GetValueAsString(irow,icol)

    return et.tostring(rattree)

if __name__ == '__main__':
    ds=gdal.Open(sys.argv[1])
    rat=ds.GetRasterBand(1).GetDefaultRAT()
    sxml=serialize(rat)

    print sxml

    #Or if you want to pretty print
    import xml.dom.minidom as md
    print md.parseString(sxml).toprettyxml()

and here's a function to write out a CSV file.

import csv
import sys

from osgeo import gdal

def tocsv(rat,filepath):
    with open(filepath, 'wb') as csvfile:
        csvwriter = csv.writer(csvfile)

        #Write out column headers
        icolcount=rat.GetColumnCount()
        cols=[]
        for icol in range(icolcount):
            cols.append(rat.GetNameOfCol(icol))
        csvwriter.writerow(cols)

        #Write out each row.
        irowcount = rat.GetRowCount()
        for irow in range(irowcount):
            cols=[]
            for icol in range(icolcount):
                itype=rat.GetTypeOfCol(icol)
                if itype==gdal.GFT_Integer:
                    value='%s'%rat.GetValueAsInt(irow,icol)
                elif itype==gdal.GFT_Real:
                    value='%.16g'%rat.GetValueAsDouble(irow,icol)
                else:
                    value='%s'%rat.GetValueAsString(irow,icol)
                cols.append(value)
            csvwriter.writerow(cols)
0

@Luke has found a very good solution, but has also to deal with the mix format nature (plain text + minixml) of gdal/org toolset metadata format. So solutions will always have "Data Mining" parts, that will split the text and the xml stuff or normalize the info in one of the both format directions. A "in house solution" in gdalinfo like a -csv, -xml or -json switch is'nt present at the moment.

I think that gdalinfo and ogrinfo are very useful tools. On the other hand the osgeo.org developer community knows these difficulties. So you might participate at the discourse and give some of the requested comments, to improve the toolsets.

http://trac.osgeo.org/gdal/wiki/rfc44_gdalinfoxml

Or tailor your own solution at the OS platform you want. Implementation examples can also be found here in the rfc44.

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.