SPECIFICATION FOR 3D GRID FILES IN GRASS

Directory Structure

The file format consists of a mapset element grid3 which contains a directory for every map. The elements for each map are
        3d region file
        color file (color)
	categories file (cats)
        range file (range)
        timestamp file /* not yet implemented */
        cell file (cell)
	header file (cellhd)
        a directory containing display files  /* not yet */
There is also a colr2 mechanism provided. colr2 color tables are stored in grid3/colr2/MAPSET/MAP.

Note: color, categories, and the range can be used in the same way as in 2d GRASS with the exception of reading and writng. 3d read and write functions have to be used for this purpose.

Data File Format

Cell-values can be either double or float. Values are written in XDR-format. NULL-values are stored in an embedded fashion. The cell-values are organized in 3d-tiles. The tile dimensions can be chosen when a new map is opened. Every tile of a map has the same dimension except those which overlap the region boundaries. Compression is used to store tiles.

The data file has the following format:

	xdr_int nofBytesLong;
	xdr_int nofBytesUsed;
	encoded_long indexOffset;
	compressed_tile[] tiles;
	compressed_encoded_long[] index;

Transportability of data file

All numbers stored in the data file are either XDR-encoded or encoded by some other method (for variables of type long only).

Tile Data NULL-values

G3D uses the same functions as 2d GRASS to set and test NULL-values. The storage in the file is different though. NULL-values are stored with a special bit-pattern if maximum precision is chosen. They are stored by adding an additional bit if the precision is smaller.

Tile Data Compression

There are three methods of compression provided. The compression methods can either be those defined by default, set by environment variables or explicitly set at run-time.
	Precision
	RLE
	LZW
Precision indicates how many of the mantissa bits should be stored on file. This number can be any value between 0 and 23 for floats and between 0 and 52 for doubles. Choosing a small precision is the most effective way to achieve good compression.

RLE takes advantage of possible repetitions of the exponents and the NULL-bit structure. Using RLE does not significantly increase the running time. If for some tile the non-RLEed version is smaller in size, RLE is not used for this tile.

LZW compression is used on top of RLE. It does not consistently achieve significant improvements but adds to the running time. If for some tile the non-LZW compressed version is smaller in size, LZW compression is not used for this tile.

The default and suggested setting is to use precision and RLE.

Additional compression is achieved by storing the extra NULL-bit in a separate bit-array. Using this scheme NULL-values need not actually be represented in the array of cell values. This array is stored together with the cell-values of the tile.


Tile Cache

Tiles can either be read and written directly or use an intermediate cache instead.

In non-cache mode the application should only use the functions G3d_readTile () and G3d_writeTile () to read and write tiles. The application can use one tile provided by the map structure as buffer. See G3d_getTilePtr ().

In cache mode the application can access cell-values directly by their coordinates. The corresponding functions are G3d_getValue () and G3d_putValue () and their corresponding typed versions.

If the map is new then in addition to the memory-cache a file-cache is provided. This allows the application to write the cell-values in any arbitrary order. Tiles are written (flushed) to the data-file either at closing time or if explicitly requested.

If the map is new G3d_getValue () can be used even if the tile which contains the cell has already been flushed to the data file. In this case the tile is simply read back into the memory-cache from the data file.

Explicitly flushing tiles can have the advantage that less disk space is occupied since tiles are stored in a uncompressed fashion in the file-cache. Flushing tiles explicitly can cause problems with accuracy though if precision is less than the maximum precision and an already flushed value is used for computations later in the program.

The type of the cell-values of the tiles in memory can be chosen independently of the type of the tiles in the file. Here, once again one has to consider possible problems arising from mixing different precisions. As an example consider the case where the data is stored in the file with double precision and the tiles are stored in memory in single precision. Then using G3d_getValue () will actually return a double precision number whose precision is only 23 bits. It is therefore a good idea to use the types in the memory consistently.


Header File

The header file has the following format:
Proj: 1
Zone: 1
North: 2.0000000000000
South: 0.5000000000000
East: 4.0000000000000
West: 3.0000000000000
Top: 6.0000000000000
Bottom: 5.0000000000000
nofRows: 30
nofCols: 20
nofDepths: 14
e-w resol: 0.05
n-s resol: 0.05
t-b resol: 0.071428571
TileDimensionX: 8
TileDimensionY: 8
TileDimensionZ: 8
CellType: double
useCompression: 1
useRle: 1
useLzw: 0
Precision: -1
nofHeaderBytes: 12
useXdr: 1
hasIndex: 1
Units: none
Except for the first 14 fields the entries of the header file should not be modified. The precision value -1 indicates that maximum precision is used.

Binary files not in G3D format can be read by the library. The following actions have to be taken: Make a new map directory in the grid3 element of the mapset (say mymap). Copy the file into mymap/cell and generate a header file mymap/cellhd. In the following example the relevant values of mymap/cellhd are shown.

TileDimensionX: A
TileDimensionY: B
TileDimensionZ: C
useCompression: 0
useRle: 0
useLzw: 0
Precision: -1
nofHeaderBytes: X
useXdr: 0
hasIndex: 0
The values of A, B, and C have to be chosen according to one of the following patterns:
A >= 1, B == 1, C == 1, or
A >= nofRows, B >= 1, C == 1, or
A >= nofRows, B >= nofCols, C >= 1.
A larger tile size reduces the number of tile-reads. If in the third pattern C is chosen larger than or equal to nofDepths, the entire region is considered one large tile.

The value nofHeaderBytes indicates the offset in the file to the first data entry.

For performance reasons it is a good idea to use function G3d_retile() before using the file in other applications.


Region Structure

typedef struct{

    double north, south;
    double east, west;
    double top, bottom;
  
    int rows, cols, depths;/* data dimensions in cells */

    double ns_res, ew_res, tb_res;

    int proj;  /* Projection (see gis.h) */
    int zone;  /* Projection zone (see gis.h) */

} G3D_Region;

Windows

Window capability similar to that of 2d GRASS is provided. Additional features are the window for the third dimension as well as the possibility to choose a different window for every map. The window can be specified at the time of opening an old map. It can be modified at any time later in the program. The resampling method can be the default nearest neighbor method as well as an application provided method.

The default 3d window file is WIND3 located in the mapset. Application programs should use G3d_useWindowParams () to allow the user to overwrite this default.

The window file has the following format.

Proj: 1
Zone: 1
North: 2.0
South: 0.5
East: 4.0
West: 3.0
Top: 5.0
Bottom: 6.0
nofRows: 30
nofCols: 20
nofDepths: 14
e-w resol: 0.05000000000000000
n-s resol: 0.05000000000000000
t-b resol: 0.07142857142857142
Note: after reading the window file the fields e-w, n-s, and t-b are recomputed internally.

A note about windows and caching. Caching is performed on the level of tiles read from the file. There is no caching performed on resampled data. This is different from 2d GRASS since resampling for a specific value is performed every time it is being accessed.


Masks

G3D provides a mask for the 3d region. The mask structure is automatically initialized at the time the first file is opened. The same structure is used for all the files. The default for every file is that the mask is turned off. If masking should be performed, the application program has to turn on masking explicitly. If masking is turned on for a file, the cell-values of a tile are automatically checked against the mask. Values which are masked out, are set to NULL.

Note: changing the status of masking after one or more tiles have already been read does not affect the tiles which are already stored in the cache.

Any arbitrary g3d file can be used as mask file: NULL-values are interpreted as "mask-out", all other values are interpreted as "don't mask out". Using r3.mask to convert a g3d file into a mask file instead of simply copying (or renaming) the directory will significantly reduce to amount of disk space and the access time for the mask.


Include File

Exported G3D constants and structures can be found in G3d.h.