00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 #include <io.h>
00064
00066 int
00067 read_netcdf_var_2d(double **buf, info_field_struct *info_field, proj_struct *proj, char *filename, char *varname,
00068 char *dimxname, char *dimyname, int *nlon, int *nlat, int outinfo) {
00084 int istat;
00085
00086 size_t dimval;
00087
00088 int ncinid;
00089 int varinid;
00090 int projinid;
00091 nc_type vartype_main;
00092 int varndims;
00093 int vardimids[NC_MAX_VAR_DIMS];
00094 int londiminid;
00095 int latdiminid;
00096
00097 size_t start[3];
00098 size_t count[3];
00099
00100 float valf;
00101 int vali;
00102 char *tmpstr = NULL;
00103 size_t t_len;
00104
00105 float *proj_latin = NULL;
00106 int npts = 0;
00107 char *grid_mapping = NULL;
00108
00109
00110 tmpstr = (char *) malloc(MAXPATH * sizeof(char));
00111 if (tmpstr == NULL) alloc_error(__FILE__, __LINE__);
00112
00113
00114
00115
00116 if (outinfo == TRUE)
00117 printf("%s: Opening for reading NetCDF input file %s\n", __FILE__, filename);
00118 istat = nc_open(filename, NC_NOWRITE, &ncinid);
00119 if (istat != NC_NOERR) {
00120 printf("%s: Failed Opening for reading NetCDF input file %s\n", __FILE__, filename);
00121 handle_netcdf_error(istat, __FILE__, __LINE__);
00122 return -1;
00123 }
00124
00125 if (outinfo == TRUE)
00126 printf("%s: READ %s %s\n", __FILE__, varname, filename);
00127
00128
00129 istat = nc_inq_dimid(ncinid, dimyname, &latdiminid);
00130 if (istat != NC_NOERR) { handle_netcdf_error(istat, __FILE__, __LINE__); return -1; }
00131 istat = nc_inq_dimlen(ncinid, latdiminid, &dimval);
00132 if (istat != NC_NOERR) { handle_netcdf_error(istat, __FILE__, __LINE__); return -1; }
00133 *nlat = (int) dimval;
00134
00135 istat = nc_inq_dimid(ncinid, dimxname, &londiminid);
00136 if (istat != NC_NOERR) { handle_netcdf_error(istat, __FILE__, __LINE__); return -1; }
00137 istat = nc_inq_dimlen(ncinid, londiminid, &dimval);
00138 if (istat != NC_NOERR) { handle_netcdf_error(istat, __FILE__, __LINE__); return -1; }
00139 *nlon = (int) dimval;
00140
00141
00142 istat = nc_inq_varid(ncinid, varname, &varinid);
00143 if (istat != NC_NOERR) { handle_netcdf_error(istat, __FILE__, __LINE__); return -1; }
00144
00147
00148 istat = nc_inq_var(ncinid, varinid, (char *) NULL, &vartype_main, &varndims, vardimids, (int *) NULL);
00149 if (istat != NC_NOERR) { handle_netcdf_error(istat, __FILE__, __LINE__); return -1; }
00150
00151
00152 if (varndims != 2 && varndims != 1) {
00153 (void) fprintf(stderr, "%s: Error NetCDF type and/or dimensions nlon %d nlat %d. The dimensions of the data variable is neither 1D or 2D...\n", __FILE__, *nlon, *nlat);
00154 (void) free(tmpstr);
00155 istat = ncclose(ncinid);
00156 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00157 return -1;
00158 }
00159
00160 if (varndims == 1) {
00161 if ((*nlat) != (*nlon)) {
00162 (void) fprintf(stderr, "%s: Error NetCDF type and/or dimensions nlon %d nlat %d. When dimensions are specified as 1D, nlon must be equal to nlat because the grid cannot be assumed to be regular in latitude and longitude.\n", __FILE__, *nlon, *nlat);
00163 (void) free(tmpstr);
00164 istat = ncclose(ncinid);
00165 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00166 return -1;
00167 }
00168 npts = *nlon;
00169 *nlat = 0;
00170 }
00171
00172
00173 if (info_field != NULL) {
00174
00175 if (vartype_main == NC_FLOAT) {
00176 istat = nc_get_att_float(ncinid, varinid, "missing_value", &valf);
00177 if (istat != NC_NOERR)
00178 info_field->fillvalue = -9999.0;
00179 else
00180 info_field->fillvalue = (double) valf;
00181 }
00182 else if (vartype_main == NC_DOUBLE) {
00183 istat = nc_get_att_double(ncinid, varinid, "missing_value", &(info_field->fillvalue));
00184 if (istat != NC_NOERR)
00185 info_field->fillvalue = -9999.0;
00186 }
00187
00188
00189 istat = nc_inq_attlen(ncinid, varinid, "coordinates", &t_len);
00190 if (istat == NC_NOERR) {
00191 istat = nc_get_att_text(ncinid, varinid, "coordinates", tmpstr);
00192 if (istat == NC_NOERR) {
00193 if (tmpstr[t_len-1] != '\0')
00194 tmpstr[t_len] = '\0';
00195 info_field->coordinates = strdup(tmpstr);
00196 }
00197 else
00198 info_field->coordinates = strdup("lon lat");
00199 }
00200 else
00201 info_field->coordinates = strdup("lon lat");
00202
00203
00204 istat = nc_inq_attlen(ncinid, varinid, "grid_mapping", &t_len);
00205 if (istat == NC_NOERR) {
00206 istat = nc_get_att_text(ncinid, varinid, "grid_mapping", tmpstr);
00207 if (istat == NC_NOERR) {
00208 if (tmpstr[t_len-1] != '\0')
00209 tmpstr[t_len] = '\0';
00210 info_field->grid_mapping = strdup(tmpstr);
00211 }
00212 else
00213 info_field->grid_mapping = strdup("unknown");
00214 }
00215 else
00216 info_field->grid_mapping = strdup("unknown");
00217
00218
00219 istat = nc_inq_attlen(ncinid, varinid, "units", &t_len);
00220 if (istat == NC_NOERR) {
00221 istat = nc_get_att_text(ncinid, varinid, "units", tmpstr);
00222 if (istat == NC_NOERR) {
00223 if (tmpstr[t_len-1] != '\0')
00224 tmpstr[t_len] = '\0';
00225 info_field->units = strdup(tmpstr);
00226 }
00227 else
00228 info_field->units = strdup("unknown");
00229 }
00230 else
00231 info_field->units = strdup("unknown");
00232
00233
00234 istat = nc_inq_attlen(ncinid, varinid, "height", &t_len);
00235 if (istat == NC_NOERR) {
00236 istat = nc_get_att_text(ncinid, varinid, "height", tmpstr);
00237 if (istat == NC_NOERR) {
00238 if (tmpstr[t_len-1] != '\0')
00239 tmpstr[t_len] = '\0';
00240 info_field->height = strdup(tmpstr);
00241 }
00242 else
00243 info_field->height = strdup("unknown");
00244 }
00245 else
00246 info_field->height = strdup("unknown");
00247
00248
00249 istat = nc_inq_attlen(ncinid, varinid, "long_name", &t_len);
00250 if (istat == NC_NOERR) {
00251 istat = nc_get_att_text(ncinid, varinid, "long_name", tmpstr);
00252 if (istat == NC_NOERR) {
00253 if (tmpstr[t_len-1] != '\0')
00254 tmpstr[t_len] = '\0';
00255 info_field->long_name = strdup(tmpstr);
00256 }
00257 else
00258 info_field->long_name = strdup(varname);
00259 }
00260 else
00261 info_field->long_name = strdup(varname);
00262 }
00263
00264
00265 if (proj != NULL) {
00266 if (info_field == NULL)
00267 grid_mapping = strdup("unknown");
00268 else
00269 grid_mapping = strdup(info_field->grid_mapping);
00270
00271 if ( !strcmp(grid_mapping, "Lambert_Conformal") ) {
00272 istat = nc_inq_varid(ncinid, grid_mapping, &projinid);
00273 if (istat != NC_NOERR) { handle_netcdf_error(istat, __FILE__, __LINE__); return -1; }
00274 }
00275 else if ( !strcmp(grid_mapping, "rotated_latitude_longitude") ) {
00276 istat = nc_inq_varid(ncinid, grid_mapping, &projinid);
00277 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00278 }
00279 if (proj->name != NULL) {
00280 if ( strcmp(grid_mapping, "Lambert_Conformal") && strcmp(grid_mapping, "Latitude_Longitude") &&
00281 ( !strcmp(proj->name, "Latitude_Longitude") || !strcmp(proj->name, "Lambert_Conformal") ) ) {
00282 (void) free(grid_mapping);
00283 grid_mapping = strdup(proj->name);
00284 }
00285 else if ( strcmp(grid_mapping, "rotated_latitude_longitude") && !strcmp(proj->name, "rotated_pole") ) {
00286 (void) free(grid_mapping);
00287 grid_mapping = strdup("rotated_latitude_longitude");
00288 }
00289 }
00290 if ( !strcmp(grid_mapping, "Lambert_Conformal") ) {
00291
00292
00293
00294
00295
00296
00297
00298
00299 istat = nc_get_var1_int(ncinid, projinid, 0, &vali);
00300 if (istat != NC_NOERR) { handle_netcdf_error(istat, __FILE__, __LINE__); return -1; }
00301 proj->name = strdup(grid_mapping);
00302 istat = get_attribute_str(&(proj->grid_mapping_name), ncinid, projinid, "grid_mapping_name");
00303
00304 proj_latin = (float *) malloc(2 * sizeof(float));
00305 if (proj_latin == NULL) alloc_error(__FILE__, __LINE__);
00306 istat = nc_get_att_float(ncinid, projinid, "standard_parallel", proj_latin);
00307 proj->latin1 = (double) proj_latin[0];
00308 proj->latin2 = (double) proj_latin[1];
00309 (void) free(proj_latin);
00310
00311 istat = nc_get_att_double(ncinid, projinid, "longitude_of_central_meridian", &(proj->lonc));
00312 istat = nc_get_att_double(ncinid, projinid, "latitude_of_projection_origin", &(proj->lat0));
00313 istat = nc_get_att_double(ncinid, projinid, "false_easting", &(proj->false_easting));
00314 istat = nc_get_att_double(ncinid, projinid, "false_northing", &(proj->false_northing));
00315
00316 }
00317 else if ( !strcmp(grid_mapping, "rotated_latitude_longitude") ) {
00318
00319
00320
00321
00322
00323 istat = nc_get_var1_int(ncinid, projinid, 0, &vali);
00324 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00325 proj->name = strdup("rotated_pole");
00326 istat = get_attribute_str(&(proj->grid_mapping_name), ncinid, projinid, "grid_mapping_name");
00327
00328 istat = nc_get_att_double(ncinid, projinid, "grid_north_pole_latitude", &(proj->latpole));
00329 istat = nc_get_att_double(ncinid, projinid, "grid_north_pole_longitude", &(proj->lonpole));
00330
00331 }
00332 else if ( !strcmp(grid_mapping, "Latitude_Longitude") ) {
00333 proj->name = strdup(grid_mapping);
00334 proj->grid_mapping_name = strdup("Latitude_Longitude");
00335 proj->latin1 = 0.0;
00336 proj->latin2 = 0.0;
00337 proj->lonc = 0.0;
00338 proj->lat0 = 0.0;
00339 proj->false_easting = 0.0;
00340 proj->false_northing = 0.0;
00341 }
00342 else if ( !strcmp(grid_mapping, "list") ) {
00343 proj->name = strdup(grid_mapping);
00344 proj->grid_mapping_name = strdup("list");
00345 proj->latin1 = 0.0;
00346 proj->latin2 = 0.0;
00347 proj->lonc = 0.0;
00348 proj->lat0 = 0.0;
00349 proj->false_easting = 0.0;
00350 proj->false_northing = 0.0;
00351 }
00352 else {
00353 (void) fprintf(stderr, "%s: WARNING: No projection parameter available for %s.\n", __FILE__, grid_mapping);
00354 (void) fprintf(stderr, "%s: WARNING: Assuming list of longitude and latitude points.\n", __FILE__);
00355 proj->name = strdup("list");
00356 proj->grid_mapping_name = strdup("list");
00357 proj->latin1 = 0.0;
00358 proj->latin2 = 0.0;
00359 proj->lonc = 0.0;
00360 proj->lat0 = 0.0;
00361 proj->false_easting = 0.0;
00362 proj->false_northing = 0.0;
00363 }
00364 (void) free(grid_mapping);
00365 }
00366
00367 if (varndims == 2) {
00368
00369 start[0] = 0;
00370 start[1] = 0;
00371 start[2] = 0;
00372 count[0] = (size_t) *nlat;
00373 count[1] = (size_t) *nlon;
00374 count[2] = 0;
00375
00376 (*buf) = (double *) malloc((*nlat)*(*nlon) * sizeof(double));
00377 if ((*buf) == NULL) alloc_error(__FILE__, __LINE__);
00378 }
00379 else if (varndims == 1) {
00380
00381 start[0] = 0;
00382 start[1] = 0;
00383 start[2] = 0;
00384 count[0] = (size_t) npts;
00385 count[1] = 0;
00386 count[2] = 0;
00387
00388 (*buf) = (double *) malloc(npts * sizeof(double));
00389 if ((*buf) == NULL) alloc_error(__FILE__, __LINE__);
00390 }
00391
00392
00393 istat = nc_get_vara_double(ncinid, varinid, start, count, *buf);
00394 if (istat != NC_NOERR) { handle_netcdf_error(istat, __FILE__, __LINE__); return -1; }
00395
00396
00397 istat = ncclose(ncinid);
00398 if (istat != NC_NOERR) { handle_netcdf_error(istat, __FILE__, __LINE__); return -1; }
00399
00400
00401 (void) free(tmpstr);
00402
00403
00404 return 0;
00405 }