/* This example shows how to retrieve lon/lat values from HDF-EOS2 grid data. */

#include <mfhdf.h>
#include <hdf.h>
#include <HdfEosDef.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
	int32 gridfile1;
	int32 grid1;
	int32 grid1_xdim;
	int32 grid1_ydim;
	float64 grid1_upleft[2];
	float64 grid1_lowright[2];
	int32 grid1_projcode;
	int32 grid1_zone;
	int32 grid1_sphere;
	float64 grid1_params[16];
	int32 grid1_pixreg;
	int32 grid1_origin;
	int32 *grid1_row;
	int32 *grid1_col;
	float64 *grid1_lon;
	float64 *grid1_lat;
	int32 datafield1rank;
	int32 datafield1dimsize[32];
	int32 datafield1type;
	char datafield1dimname[512];
	float32 *datafield1data;
	int32 i, j, k;

	/* Open 'AIRS.2002.09.01.L3.RetQuant_H030.v5.0.14.0.G07191213218.hdf' using grid API */
	if ((gridfile1 = GDopen("AIRS.2002.09.01.L3.RetQuant_H030.v5.0.14.0.G07191213218.hdf", DFACC_RDONLY)) == -1) {
		fprintf(stderr, "error: cannot open grid 'AIRS.2002.09.01.L3.RetQuant_H030.v5.0.14.0.G07191213218.hdf'\n");
		return -1;
	}

	/* Open a grid named 'L3Quant' */
	if ((grid1 = GDattach(gridfile1, "L3Quant")) == -1) {
		fprintf(stderr, "error: cannot attach to 'L3Quant'\n");
		return -1;
	}

	/* Retrieve dimensions and X-Y coordinates of corners from 'L3Quant' */
	if ((GDgridinfo(grid1, &grid1_xdim, &grid1_ydim, grid1_upleft, grid1_lowright)) == -1) {
		fprintf(stderr, "error: cannot get grid information from 'L3Quant'\n");
		return -1;
	}

	/* Retrieve all GCTP projection information from 'L3Quant' */
	if ((GDprojinfo(grid1, &grid1_projcode, &grid1_zone, &grid1_sphere, grid1_params)) == -1) {
		fprintf(stderr, "error: cannot get projection information from 'L3Quant'\n");
		return -1;
	}

	/* Retrieve pixel registration information from 'L3Quant' */
	if ((GDpixreginfo(grid1, &grid1_pixreg)) == -1) {
		fprintf(stderr, "error: cannot get pixel registration information from 'L3Quant'\n");
		return -1;
	}

	/* Retrieve grid pixel origin from 'L3Quant' */
	if ((GDorigininfo(grid1, &grid1_origin)) == -1) {
		fprintf(stderr, "error: cannot get pixel origin information from 'L3Quant'\n");
		return -1;
	}

	/* Allocate buffer for row */
	if ((grid1_row = malloc(sizeof(int32) * 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(int32) * 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(float64) * 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(float64) * grid1_xdim * grid1_ydim)) == NULL) {
		fprintf(stderr, "error: cannot allocate memory for latitude\n");
		return -1;
	}
	/* Retrieve lon/lat values for 'L3Quant' */
	if ((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 'L3Quant'\n");
		return -1;
	}
	for (i = 0; i < 4; ++i) {
		for (j = 0; j < 5; ++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 'Entropy' datafield */
	if ((GDfieldinfo(grid1, "Entropy", &datafield1rank, datafield1dimsize, &datafield1type, datafield1dimname)) == -1) {
		fprintf(stderr, "error: cannot get the field info for 'Entropy'\n");
		return -1;
	}
	/* Allocate buffer for 'Entropy' */
	if ((datafield1data = malloc(sizeof(float32) * 200 * 36 * 72)) == NULL) {
		fprintf(stderr, "error: cannot allocate memory for 'Entropy'\n");
		return -1;
	}
	/* Read data from 'Entropy' */
	if ((GDreadfield(grid1, "Entropy", NULL, NULL, NULL, datafield1data)) == -1) {
		fprintf(stderr, "error: cannot read field 'Entropy'\n");
		return -1;
	}
	/* Dump data from 'Entropy' */
	for (i = 0; i < 1; ++i) {
		for (j = 0; j < 4; ++j) {
			for (k = 0; k < 5; ++k) {
				printf("%f ", datafield1data[k + 72 * (j + 36 * i)]);
			}
			printf("\n");
		}
		printf("\n");
	}
	/* Release the buffer for 'Entropy' */
	free(datafield1data);

	/* Close the grid named 'L3Quant' */
	if ((GDdetach(grid1)) == -1) {
		fprintf(stderr, "error: cannot detach from 'L3Quant'\n");
		return -1;
	}

	/* Close 'AIRS.2002.09.01.L3.RetQuant_H030.v5.0.14.0.G07191213218.hdf' */
	if ((GDclose(gridfile1)) == -1) {
		fprintf(stderr, "error: cannot close grid 'AIRS.2002.09.01.L3.RetQuant_H030.v5.0.14.0.G07191213218.hdf'\n");
		return -1;
	}

	return 0;
}

