hdfeos2netcdf -- Unsupported

The hdfeos2netcdf is a tool that converts an HDF-EOS2 file or an HDF-EOS5 file to an netCDF file. This program can convert only grid and swath data; point data cannot be converted. The format of netCDF files this program creates is netCDF-3, not netCDF-4.

Installing hdfeos2netcdf

This program requires several libraries: HDF4external , HDF5external , HDF-EOS2, HDF-EOS5 , netCDF-3external and HE2HE5 . Users need to set paths to those libraries in the Makefile. Then, typing make will make a binary hdfeos2netcdf.

Users need to be careful when they build the HDF4 library because the HDF4 library may conflict with the netCDFexternal library. Since part of netCDFexternal API is implemented in HDF4 library, both libraries export exactly same symbols, which results in linker errors. To prevent this error, users need to specify --disable-netcdf switch when the HDF4 library is configured.

If netCDF-4external code is used with the HDF5 library to build netCDF library, users may need to add -lhdf5_hl flag to HDFLIBS in Makefile.

Using hdfeos2netcdf

This program takes two command-line arguments: the HDF-EOS input file and the netCDF output file. If the input file contains point data, an error will arise.

As README file included in the package explains, the structural difference between HDF-EOS and netCDF (classic) is an issue; (classic) netCDF format does not allow multiple groups while the input HDF-EOS file can contain multiple grids and swaths. For example, a problem arises when the input file contains two grids and they have data fields with the same name. This program avoids this problem by mangling variable names; grid name is prefixed to the variable name.

Another issue is related to the projection of grid data in HDF-EOS files. HDF-EOS grid data saves space by keeping only a few parameters instead of entire longitude and latitude data. This method does not lose any information because the HDF-EOS library can calculate longitude and latitude values from those parameters. However, netCDF requires latitude and longitude data to be present. To that end, this program calculates longitude and latitude values, and stores them at the output file. However, this longitude/latitude conversion has limitation; the generated longitude and latitude are always one-dimensional. If the projection method needs two-dimensional longitude and latitude values, the conversion is not complete.

In swath data, longitude and latitude variables are usually two-dimensional, which is not supported by netCDF format. By following CF conventionsexternal, this program can generate coordinates attribute, which is required by CF conventions, to variables. However, we noticed that the coordinates attribute is written only when dimension maps are not used in swath.

Dimension maps in HDF-EOS swath data also introduce a problem. With dimension maps, data fields and geo-location fields have different sizes. This is not supported by netCDF format. A possible solution to resolve this issue is to generate adjusted geo-location fields, but this program does not do.

We found a few problems while testing this program. First, this program may crash while converting grid attributes of string type. Second, this program may not find dimensions of grid data, which aborts the conversion. Also, we found a potential problem that may introduce buffer-overrun. To avoid this problem, users may need to apply the following changes:

Figure 1 Patch to fix problems
--- hdfeos-netcdf/grids.c2004-10-07 12:07:21.000000000 -0500
+++ hdfeos-netcdf_mod/grids.c 2009-05-18 11:27:02.000000000 -0500
@@ -244,8 +244,10 @@
/* For each dimension, make an entry in the dimension map */
dimname = dimnamebuf;
for(i=0; i<numdim; i++) {
- struct dment *olddim = find_dimension(dmap, dimname);
+/* THG: end_name() extracts one dimension name from the list */
+ struct dment *olddim;
end_name(dimname);
+ olddim = find_dimension(dmap, dimname);
if(olddim == NULL) {
int newdimid;
TRACE((stderr, "defining dimension |%s|, size %d\n",
@@ -736,7 +738,8 @@
int tsignp;

end_name(attname);
-ncattname = newstring(strlen(attname));
+/* THG: reserve space for null character too */
+ncattname = newstring(strlen(attname) + 1);
sprintf(ncattname, "%s", attname);
fix_nc_name(ncattname);
TRACE((stderr, "Attribute |%s| moves to |%s|\n", attname, ncattname));
@@ -784,6 +787,8 @@
code work, we smack it to 1 here.
*/
nctype = NC_CHAR;
+ /* THG: attsize was too small to hold the string */
+ attsize = atteltcount;
atteltcount = tsize;
tsize = 1;
break;
@@ -792,7 +797,8 @@
spit_status(-1, "Unhandled attribute type");
break;
}
-attsize = atteltcount * tsize;
+if (nctype != NC_CHAR)
+ attsize = atteltcount * tsize;

if(attsize < 9)
attentbuf = (void *)tempatt;


Last modified: 11/11/2020
About Us | Contact Info | Archive Info | Disclaimer
Sponsored by Subcontract number 4400528183 under Raytheon Contract number NNG15HZ39C, funded by NASA / Maintained by The HDF Group