/****************************************************************************
 *   ggrid.h : 
 *   		header file for GFC Grid class.
 *
 *   Change Log :
 *		 June 7, 1998 Initial version,  Liujian Qian
 *
 *   $Id: gadt_grid.h,v 1.6 1999/02/23 04:23:43 qian Exp $
 ***************************************************************************/
#ifndef __GGRID_H__
#define __GGRID_H__

#include "gadt.h"

struct GGridMeta
{
    double 	geo_xlow;	//longitude/latitude
    double 	geo_ylow;
    double 	cell_size_x;	//size of each cell along x/lon dimension
    double 	cell_size_y;	//size of each cell along y/lat dimension
    GeoUnit	cell_unit; 	//unit for cell size
    
    int 	n_rows; 	//number of rows and columns
    int 	n_columns;		
    int		n_bands;
    int 	easting;	// false coordnates.
    int 	northing;	//
    int 	flags;		//flags for the grid
    int		compressed;	//whether the grid file is compressed
    char 	tag[128];	//a tag (key) string for the grid

    float 	max_val;	//some statistics of the grid
    float 	min_val;
    float 	avg_val;
    float 	ignore_val; 	//background/invalid/no-data values
};


/**
 * GGrid
 * This is the class for grids which are regular 2D arrays of 
 * cells. GFC grids are automatically decomposed into slabs (GSlab)
 * when stored to permanent media, although this fact is largely
 * hidden from general GGrid user.  GGrid cells always contain values
 * of the C float type.
 *
 * GGrid is composed of a meta information struct (GGridMeta), a
 * custom grid header (an opaque block of data supplied by the user),
 * and the actual body of the cell values. The physical access to
 * the cells is performed through an GGridIO object, which maintains
 * a global cache of grid slabs to optimize the I/O. GFC provides a
 * subclass of GGridIO which performs file based grid I/O. Other
 * types of grid I/O, such as those based on database access methods,
 * can also be plugged in by implementing differnt subclasses of 
 * GGridIO. GGridIO associates the slabs (hence the cells) in the cache
 * with the grids through grid tags. Grid tags are strings that uniquely 
 * identify a grid when the program runs. Tags are automatically set to the
 * name of the grid file when file-based grid I/O is used. Tags may also
 * be database keys when database access methods are used for grid I/O,
 * in which case the user is responsible for setting up the tags. The 
 * default grid I/O class is GGridIOFile. This can however be changed by
 * calling the global function installGridIOHandler().
 *
 * The physical layout of a grid (when stored to a file etc) is: 
 *	GGridMeta meta_info;
 *	int	  custom_header_size;
 *	char*     custom_header;
 *	int	  num_slabs;
 *	GSlabDesc *slab_descriptors;
 *	GSlab	  *slabs;
 * Everything before the actual slab data ('slabs') is collectively
 * refered as GGridHeader.
 *
 * Many existing image and GIS raster data can also be imported as
 * GGrid objects. The importing interface is defined by the generic
 * GGridImporter class. In order to support a particular data format,
 * such as USGS DEM, one only needs to implement a subclass of GGridImporter,
 * (say GGridImporter_DEM), and install an instance of such a custom
 * importer in the GGrid object prior to calling the generic
 * GGrid::importFromFile() method.
 */
class GGrid : GSpatial 
{
    static	GGridIO*	io_guy;
    
protected:
    GGridMeta	meta;
    int		custom_hdr_size;
    char*	custom_hdr;
    
public:
    NOP		GGrid(GCellType t);
    NOP		GGrid(GCellType t, int ncols, int nrows);
    NOP		GGrid(const char* grid_file);
    NOP		GGrid(DataPipe& hdr_p);
    NOP		GGrid(const GGrid& a);
    GGrid&	operator=(const GGrid& a);

    virtual GType  	type() const { return _Grid; }
    virtual uint32  	getPSize() const;
    virtual Result 	init(void);
    virtual Result 	mbr(GRect& box) const;
    virtual GADT* 	clone() const { return new GGrid; }
    virtual int		cmp(const GADT& a) const;
    /**
     * print (only) the grid header
     */
    friend ostream& 	operator<<(ostream& s, const GGrid& grid);
    /**
     * generate a grid object out of a user string; the format of the
     * string: "w h V00 V01 V02... V10 V11 V12... Vwh" where w and h
     * are the width and height of the user supplied grid
     */
    virtual Result 	input     (const char* in);
    /**
     * output the grid object into a user string.
     * the format is the same as for input.
     */
    virtual Result 	output    (char*& out);
    /**
     * pack the (zipped) grid data into a pipe	
     */
    virtual Result	pack	  (DataPipe& p);
    /**
     * unpack the (zipped) data from a pipe
     */
    virtual Result 	unpack      (DataPipe& p);
    
    /**
     * create a blank grid with the given size.
     */
    virtual Result	create	    (int cols, int rows);
    
    /**
     * store the (zipped) grid data into a file
     */
    virtual Result  	saveToFile  (const char* fname);
    /**
     * load grid data from a previously stored grid file
     */
    virtual Result	loadFromFile (const char* fname);
    /**
     * install a differnt importer object. The new importer will be
     * used when importing data through the import methods.
     */
    Result		installImporter(GGridImporter* imp);
    /**
     * imports a data file. the currently installed importer is used to
     * open/read/import/close the data file. delegated to io_guy for the
     * actual work.
     */
    Result		importFromFile(const char* file);
    /**
     * imports a (in-memory) data stream. The currently installed importer
     * is used to read/import the data stream. A temporary file will be
     * created to hold the grid. delegated to io_guy for the
     * actual work.
     */
    Result		importFromData(const char* stream);


    /**
     * return the value type of cells.
     */
    inline GCellType	cellType() const {return meta.ctype;}
    
    /**
     * set a cell value. returns the old cell value.
     */
    virtual float	setCell(float val, int x, int y);
    /**
     * get the value of a cell. 
     */
    virtual float	cell (int x, int y) const;
    /**
     * return a scan line of the grid. The line_buf
     * must be preallocated with enough space (n_columns*Cell_Size)
     */
    virtual Result 	scanline (int row, char* line_buf) const;

    /**
     * set number of columns and rows of the grid.
     */
    void		setSize(int columns, int rows);

    /**
     * return number of columns
     */
    inline int		columns() const {return meta.n_columns;}
    /**
     * return number of rows
     */
    inline int		rows() const {return meta.n_rows;}
    /**
     * return the maximum value
     */
    inline float	max() const  {return (double)(meta.max_val);}
    /**
     * return maximum value for given region
     */
    float          	max(GRect& r) const;
    /**
     * return minimum value
     */
    inline float	min() const {return (double)(meta.min_val);}
    
    /**
     * return min value for given region
     */
    float          	min(GRect& r) const;
    /**
     * return average val. Note that cells with ignore_val are not
     * counted when averaing.
     */
    inline float	avg() const {return (double)(meta.avg_val);}
    /**
     * return average value for given region
     */
    float		avg(GRect& r) const;
    /**
     * return the value to be ignored (for background/non-value)
     */
    inline float  	ignore() const {return meta.ignore_val;}
    /**
     * set  ignorant value
     */
    inline void		setIgnoreValue(float v) { meta.ignore_val=v; }
    /**
     * set easting value
     */
    inline void 	setEasting(int e) { meta.easting = e; }
    /**
     * return the easting value
     */
    inline int 		easting() const {return meta.easting;}
    /**
     * set northing value
     */
    inline void 	setNorthing(int n) {meta.northing = n; }
    /**
     * return the northing value
     */
    inline int		northing() const {return meta.northing;}
    /**
     * set geographic coordinates for lower corner
     */
    inline void	 	setGeoLow (double glx, double gly) {
                                   meta.geo_xlow = glx;
				   meta.geo_ylow = gly; }
    /**
     */ 
    inline void  	geoLow (double & glx, double & gly) const { 
	                           glx = meta.geo_xlow;
				   gly=meta.geo_ylow; }
    /**
     * set the size of a cell
     */
    inline void  	setCellSizeX (double sz) {meta.cell_size_x = sz;}
    inline double	cellSizeX () const {return meta.cell_size_x; }
    inline void  	setCellSizeY (double sz) {meta.cell_size_y = sz;}
    inline double	cellSizeY () const {return meta.cell_size_y; }
    inline void		cellSize     (double& xs, double& ys) {
	                    xs = meta.cell_size_x, ys = meta.cell_size_y; }

    inline void		setCellUnit  (GeoUnit u) {meta.cell_unit = u; }
    inline GeoUnit	cellUnit  () const {return meta.cell_unit; }

    /**
     * get the size of a cell
     */ 
    inline int   	cellValueSize () const 
                             {return getCellValueSize(meta.ctype); }

    /**
     * calculate the statistics (min, max, average) of the
     * grid. These statistics are updated and stored permanantly
     * in the grid header.
     */
    virtual Result	updateStats();    
};


/**
 * return the Morton address for point (x,y)
 */
extern 	 MAD	XY2M(int x, int y);
/**
 * get the x,y coordinates  with given Mortion address.
 */
extern void	M2XY(MAD addr, int& x, int& y);

#endif

Documentation generated by lqian@lqian-sun on Wed Jul 14 09:36:10 EDT 1999