[Gdal-dev] Raster Attribute Tables (RATs)
Frank Warmerdam
fwarmerdam at gmail.com
Thu Jul 28 13:54:20 EDT 2005
Folks,
I have finally started work on "raster attribute tables" (or RATs) for GDAL.
This is intended to be a data structure capturing various sorts of information
that can be associated with ranges of pixel values. This would include:
o Color tables where a specific color is associated with each
integer raster value. Currently handled by GDALColorTable
o Color tables where ranges of values are assigned one color value.
Currently addressed by the COLOR_TABLE_RULE metadata returned
by the GRASS driver, but no where else.
o Color tables where a range of pixel values are assigned a range of
colors. That is, the color for a particular pixel value is determined by
looking up the category it falls into and interpolating the value between
the start and end value for that category based on where the pixel value
is between the category minimum and maximum. This is also currently
only handled by the GRASS COLOR_TABLE_RULE metadata mechanism.
o Histogram information, where histogram counts are available for for some
binning pattern of the data. This is currently handled via the
GetHistogram(), GetDefaultHistogram() and SetDefaultHistogram() methods
on the GDALRasterBand.
o Class names for categories ... currently handled by the GetCategoryNames()
method on the GDALRasterBand.
o Other generic information, such as long class names, other computed
statistics, etc.
It is still unclear to what extent this new mechanism will replace existing
mechanisms. It is likely that it will superceed the COLOR_TABLE_RULE
mechanism implemented for the GRASS driver, but I don't expect it to
replace use of the GDALColorTable for simple paletted images. It also
won't replace the histogram mechanism. It *might* replace the
GetCategoryNames() mechanism since that is so little used.
The raster attribute table is essentially a table with one "row" for each
range of pixel values considered to belong to a class. In a classic
256 color paletted image there would be 256 classes. To hold a 16
bit histogrmam, it might need 65536 classes. For an image intended
to be colored along a single color range it might only have one class.
Each row implicitly or explicitly has a min and max pixel value defining
the range of pixel values to which the row (category/class) applies.
The table will have one or more columns. If the min/max ranges are not
"regular", then they can be explicit columns in the table. Other columns
could include "class name", "pixel count" (histogram), red, green, blue,
alpha, red_min, red_max, and so forth. Very simple tables might only have
one column (say the pixel count), while others may have most of the columns.
Each RAT would have a name, and a given GDALRasterBand might have more than
one associated with it, though normally there would be zero or one such table.
I propose to implement a GDALRasterAttributeClass table for easy
construction, and query of raster attribute tables. The interface
would look something like:
typedef enum {
GFT_Integer,
GFT_Real,
GFT_String
} GDALRATFieldType;
typedef enum {
GFU_Generic = 0,
GFU_PixelCount = 1,
GFU_Name = 2,
GFU_Min = 3,
GFU_Max = 4,
GFU_Red = 5,
GFU_Green = 6,
GFU_Blue = 7,
GFU_Alpha = 8,
GFU_RedMin = 9,
GFU_GreenMin = 10,
GFU_BlueMin = 11,
GFU_AlphaMin = 12,
GFU_RedMax = 13,
GFU_GreenMax = 14,
GFU_BlueMax = 15,
GFU_AlphaMax = 16,
GFU_Max
} GDALRATFieldUsage;
class GDALRasterAttributeTable
{
public:
GDALRasterAttributeTable();
~GDALRasterAttributeTable();
std::string GetTableName() const;
int GetCategoryCount() const;
const char *GetNameOfCol( int );
GDALRATFieldUsage GetUsageOfCol( int );
GDALRATFieldType GetTypeOfCol( int );
int GetColOfUsage( GDALRATFieldUsage );
int GetRowCount() const;
std::string GetValueAsString( int iRow, int iField ) const;
int GetValueAsInt( int iRow, int iField ) const;
double GetValueAsDouble( int iRow, int iField ) const;
void SetValue( int iRow, int iField, const char *pszValue );
void SetValue( int iRow, int iField, double dfValue);
void SetValue( int iRow, int iField, int nValue );
int GetRowOfValue( double dfValue );
int GetRowOfValue( int nValue );
int GetColorOfValue( double dfValue, GDALColorEntry *psEntry );
double GetRowMin( int iRow );
double GetRowMax( int iRow );
CPLErr CreateColumn( std::string osFieldName,
GDALRATFieldType eFieldType,
GDALRATFieldUsage eFieldUsage );
CPLErr SetLinearBinning( double dfRow0Min, double dfBinSize );
int GetRegularBinning( double *pdfRow0Min, double *pdfBinSize );
CPLXMLNode *Serialize();
CPLErr XMLInit( CPLXMLNode *, const char * );
CPLErr InitializeFromColorTable( GDALColorTable * );
};
The GDALRasterBand class would have new virtual methods to query for
or associate raster attribute tables with a band:
virtual const GDALRasterAttributeTable *
GetRasterAttributeTableRef( const char *pszTableName = NULL );
virtual char **
GetRasterAttributeTableList();
virtual CPLErr
AssociateRasterAttributeTable( GDALRasterAttributeTable * );
The GRASS and HFA (Erdas Imagine) drivers would include explicit support
for reading back the "raster attribute table" structures from those formats
directly. The GDALPamRasterBand base class used for most driver's
GDALRasterBand classes would also support these attribute tables via the
.aux.xml file.
It is not yet clear to me to what extent some of the existing functions
that overlap raster attribute tables would interact. For instance, should
the default implementation of the GetHistogram() method search for existing
RATs to satisfy a request?
I think the most common use of RATs will be for applications wishing to
preserve complex portrayal. For instance, QGIS's GRASS plugin already uses
the COLOR_TABLE_RULE metadata to get range based colormaps. It should be
upgraded to using RATs. Basically scan for a RAT with color columns and
translate accordingly. Likewise, MapServer could do the same thing,
essentially internally defining a series of CLASSes on the raster layer based
on the RAT rows.
I am putting out this preliminary design to get feedback from you, the user
community, on things you would like to accomplish with RATs and suggestions
with regard to the interface and behavior.
Best regards,
--
---------------------------------------+--------------------------------------
I set the clouds in motion - turn up | Frank Warmerdam, warmerdam at pobox.com
light and sound - activate the windows | http://pobox.com/~warmerdam
and watch the world go round - Rush | Geospatial Programmer for Rent
More information about the Gdal-dev
mailing list