/* This example shows how to retrieve lon/lat values from HDF-EOS5 grid data. */

#include <HE5_HdfEosDef.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
	hid_t gridfile1;
	hid_t grid1;
	long grid1_xdim;
	long grid1_ydim;
	double grid1_upleft[2];
	double grid1_lowright[2];
	int grid1_projcode;
	int grid1_zone;
	int grid1_sphere;
	double grid1_params[16];
	int grid1_pixreg;
	int grid1_origin;
	long *grid1_row;
	long *grid1_col;
	double *grid1_lon;
	double *grid1_lat;
	int datafield1rank;
	hsize_t datafield1dimsize[32];
	hid_t datafield1type;
	char datafield1dimname[512];
	char datafield1maxdimname[512];
	short *datafield1data;
	hsize_t i, j, k;

	/* Open 'OMI-Aura_L3-OMAEROe_2004m1001_v003-2009m0114t094640.he5' using grid API */
	if ((gridfile1 = HE5_GDopen("OMI-Aura_L3-OMAEROe_2004m1001_v003-2009m0114t094640.he5", H5F_ACC_RDONLY)) == -1) {
		fprintf(stderr, "error: cannot open grid 'OMI-Aura_L3-OMAEROe_2004m1001_v003-2009m0114t094640.he5'\n");
		return -1;
	}

	/* Open a grid named 'ColumnAmountAerosol' */
	if ((grid1 = HE5_GDattach(gridfile1, "ColumnAmountAerosol")) == -1) {
		fprintf(stderr, "error: cannot attach to 'ColumnAmountAerosol'\n");
		return -1;
	}

	/* Retrieve dimensions and X-Y coordinates of corners from 'ColumnAmountAerosol' */
	if ((HE5_GDgridinfo(grid1, &grid1_xdim, &grid1_ydim, grid1_upleft, grid1_lowright)) == -1) {
		fprintf(stderr, "error: cannot get grid information from 'ColumnAmountAerosol'\n");
		return -1;
	}

	/* Retrieve all GCTP projection information from 'ColumnAmountAerosol' */
	if ((HE5_GDprojinfo(grid1, &grid1_projcode, &grid1_zone, &grid1_sphere, grid1_params)) == -1) {
		fprintf(stderr, "error: cannot get projection information from 'ColumnAmountAerosol'\n");
		return -1;
	}

	/* Retrieve pixel registration information from 'ColumnAmountAerosol' */
	if ((HE5_GDpixreginfo(grid1, &grid1_pixreg)) == -1) {
		grid1_pixreg = HE5_HDFE_CENTER;
	}

	/* Retrieve grid pixel origin from 'ColumnAmountAerosol' */
	if ((HE5_GDorigininfo(grid1, &grid1_origin)) == -1) {
		grid1_origin = HE5_HDFE_GD_UL;
	}

	/* Allocate buffer for row */
	if ((grid1_row = malloc(sizeof(long) * grid1_xdim * grid1_ydim)) == NULL) {
		fprintf(stderr, "error: cannot allocate memory for row\n");
		return -1;
	}
	/* Allocate buffer for column */
	if ((grid1_col = malloc(sizeof(long) * grid1_xdim * grid1_ydim)) == NULL) {
		fprintf(stderr, "error: cannot allocate memory for column\n");
		return -1;
	}
	/* Fill two arguments, rows and columns */
	for (k = j = 0; j < grid1_ydim; ++j) {
		for (i = 0; i < grid1_xdim; ++i) {
			grid1_row[k] = j;
			grid1_col[k] = i;
			++k;
		}
	}
	/* Allocate buffer for longitude */
	if ((grid1_lon = malloc(sizeof(double) * grid1_xdim * grid1_ydim)) == NULL) {
		fprintf(stderr, "error: cannot allocate memory for longitude\n");
		return -1;
	}
	/* Allocate buffer for latitude */
	if ((grid1_lat = malloc(sizeof(double) * grid1_xdim * grid1_ydim)) == NULL) {
		fprintf(stderr, "error: cannot allocate memory for latitude\n");
		return -1;
	}
	/* Retrieve lon/lat values for 'ColumnAmountAerosol' */
	if ((HE5_GDij2ll(grid1_projcode, grid1_zone, grid1_params, grid1_sphere, grid1_xdim, grid1_ydim, grid1_upleft, grid1_lowright, grid1_xdim * grid1_ydim, grid1_row, grid1_col, grid1_lon, grid1_lat, grid1_pixreg, grid1_origin)) == -1) {
		fprintf(stderr, "error: cannot retrieve lon/lat values for 'ColumnAmountAerosol'\n");
		return -1;
	}
	for (i = 0; i < 7; ++i) {
		for (j = 0; j < 14; ++j)
			printf("%5.1lf/%4.1lf, ", grid1_lon[j + grid1_xdim * i], grid1_lat[j + grid1_xdim * i]);
		printf("\n");
	}
	/* Release buffer for row */
	free(grid1_row);
	/* Release buffer for column */
	free(grid1_col);
	/* Release buffer for longitude */
	free(grid1_lon);
	/* Release buffer for latitude */
	free(grid1_lat);

	/* Retrieve information about 'TerrainReflectivity' datafield */
	if ((HE5_GDfieldinfo(grid1, "TerrainReflectivity", &datafield1rank, datafield1dimsize, &datafield1type, datafield1dimname, datafield1maxdimname)) == -1) {
		fprintf(stderr, "error: cannot get the field info for 'TerrainReflectivity'\n");
		return -1;
	}
	/* Allocate buffer for 'TerrainReflectivity' */
	if ((datafield1data = malloc(sizeof(short) * 720 * 1440)) == NULL) {
		fprintf(stderr, "error: cannot allocate memory for 'TerrainReflectivity'\n");
		return -1;
	}
	/* Read data from 'TerrainReflectivity' */
	if ((HE5_GDreadfield(grid1, "TerrainReflectivity", NULL, NULL, NULL, datafield1data)) == -1) {
		fprintf(stderr, "error: cannot read field 'TerrainReflectivity'\n");
		return -1;
	}
	/* Dump data from 'TerrainReflectivity' */
	for (i = 0; i < 7; ++i) {
		for (j = 0; j < 14; ++j) {
			printf("%d ", datafield1data[j + 1440 * i]);
		}
		printf("\n");
	}
	/* Release the buffer for 'TerrainReflectivity' */
	free(datafield1data);

	/* Close the grid named 'ColumnAmountAerosol' */
	if ((HE5_GDdetach(grid1)) == -1) {
		fprintf(stderr, "error: cannot detach from 'ColumnAmountAerosol'\n");
		return -1;
	}

	/* Close 'OMI-Aura_L3-OMAEROe_2004m1001_v003-2009m0114t094640.he5' */
	if ((HE5_GDclose(gridfile1)) == -1) {
		fprintf(stderr, "error: cannot close grid 'OMI-Aura_L3-OMAEROe_2004m1001_v003-2009m0114t094640.he5'\n");
		return -1;
	}

	return 0;
}

