Commit 170c3132 authored by Uwe Schulzweida's avatar Uwe Schulzweida
Browse files

netCDF: added write support of lat/lon coordinates without dimension

parent 35ce26d8
......@@ -4,6 +4,10 @@
* using EXSE library version 1.3.2
* using CGRIBEX library version 1.6.4
2014-05-16 Uwe Schulzweida
* netCDF: added write support of lat/lon coordinates without dimension
2014-05-15 Uwe Schulzweida
* cgribexGetGrid: correct last lon when last lon < first lon
......@@ -14,7 +18,7 @@
2014-05-13 Uwe Schulzweida
* netCDF: added support for lon/lat coordinates without dimension
* netCDF: added read support for lon/lat coordinates without dimension
2014-05-12 Uwe Schulzweida
......
......@@ -281,9 +281,11 @@ void stream_check_ptr(const char *caller, stream_t *streamptr);
int streamInqFileID(int streamID);
int zaxisInqLevelID(int zaxisID, double level);
void gridDefHasDims(int gridID, int hasdims);
int gridInqHasDims(int gridID);
const char *gridNamePtr(int gridtype);
char *zaxisNamePtr(int leveltype);
int zaxisInqLevelID(int zaxisID, double level);
void streamCheckID(const char *caller, int streamID);
......
......@@ -128,6 +128,7 @@ void grid_init(grid_t *gridptr)
gridptr->angle = 0.0;
gridptr->locked = FALSE;
gridptr->lcomplex = 0;
gridptr->hasdims = TRUE;
gridptr->xname[0] = 0;
gridptr->yname[0] = 0;
gridptr->xlongname[0] = 0;
......@@ -4050,15 +4051,13 @@ void gridInqLcc2(int gridID, double *earth_radius, double *lon_0, double *lat_0,
void gridDefLaea(int gridID, double earth_radius, double lon_0, double lat_0)
{
grid_t *gridptr;
if ( reshGetStatus ( gridID, &gridOps ) == RESH_CLOSED )
{
Warning("%s", "Operation not executed.");
return;
}
gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
grid_t* gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
grid_check_ptr(gridID, gridptr);
......@@ -4077,9 +4076,7 @@ void gridDefLaea(int gridID, double earth_radius, double lon_0, double lat_0)
void gridInqLaea(int gridID, double *earth_radius, double *lon_0, double *lat_0)
{
grid_t *gridptr;
gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
grid_t* gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
grid_check_ptr(gridID, gridptr);
......@@ -4102,15 +4099,13 @@ void gridInqLaea(int gridID, double *earth_radius, double *lon_0, double *lat_0)
void gridDefComplexPacking(int gridID, int lcomplex)
{
grid_t *gridptr;
if ( reshGetStatus ( gridID, &gridOps ) == RESH_CLOSED )
{
Warning("%s", "Operation not executed.");
return;
}
gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
grid_t* gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
grid_check_ptr(gridID, gridptr);
......@@ -4120,16 +4115,37 @@ void gridDefComplexPacking(int gridID, int lcomplex)
int gridInqComplexPacking(int gridID)
{
int lcomplex;
grid_t *gridptr;
grid_t* gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
grid_check_ptr(gridID, gridptr);
return (gridptr->lcomplex);
}
void gridDefHasDims(int gridID, int hasdims)
{
if ( reshGetStatus ( gridID, &gridOps ) == RESH_CLOSED )
{
Warning("%s", "Operation not executed.");
return;
}
grid_t* gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
grid_check_ptr(gridID, gridptr);
lcomplex = gridptr->lcomplex;
gridptr->hasdims = hasdims;
}
int gridInqHasDims(int gridID)
{
grid_t* gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
grid_check_ptr(gridID, gridptr);
return (lcomplex);
return (gridptr->hasdims);
}
/*
......@@ -4148,15 +4164,13 @@ The function @func{gridDefNumber} defines the reference number for an unstructur
*/
void gridDefNumber(int gridID, const int number)
{
grid_t *gridptr;
if ( reshGetStatus ( gridID, &gridOps ) == RESH_CLOSED )
{
Warning("%s", "Operation not executed.");
return;
}
gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
grid_t* gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
grid_check_ptr(gridID, gridptr);
......@@ -4180,9 +4194,7 @@ The function @func{gridInqNumber} returns the reference number to an unstructure
*/
int gridInqNumber(int gridID)
{
grid_t *gridptr;
gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
grid_t* gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
grid_check_ptr(gridID, gridptr);
......@@ -4205,15 +4217,13 @@ The function @func{gridDefPosition} defines the position of grid in the referenc
*/
void gridDefPosition(int gridID, int position)
{
grid_t *gridptr;
if ( reshGetStatus ( gridID, &gridOps ) == RESH_CLOSED )
{
Warning("%s", "Operation not executed.");
return;
}
gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
grid_t* gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
grid_check_ptr(gridID, gridptr);
......@@ -4237,9 +4247,7 @@ The function @func{gridInqPosition} returns the position of grid in the referenc
*/
int gridInqPosition(int gridID)
{
grid_t *gridptr;
gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
grid_t* gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
grid_check_ptr(gridID, gridptr);
......@@ -4262,15 +4270,13 @@ The function @func{gridDefReference} defines the reference URI for an unstructur
*/
void gridDefReference(int gridID, const char *reference)
{
grid_t *gridptr;
if ( reshGetStatus ( gridID, &gridOps ) == RESH_CLOSED )
{
Warning("%s", "Operation not executed.");
return;
}
gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
grid_t* gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
grid_check_ptr(gridID, gridptr);
......@@ -4303,10 +4309,8 @@ The function @func{gridInqReference} returns the reference URI to an unstructure
*/
int gridInqReference(int gridID, char *reference)
{
grid_t *gridptr;
int len = 0;
gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
grid_t* gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
grid_check_ptr(gridID, gridptr);
......@@ -4337,21 +4341,17 @@ The function @func{gridDefUUID} defines the UUID for an unstructured grid.
*/
void gridDefUUID(int gridID, const char *uuid)
{
grid_t *gridptr;
if ( reshGetStatus ( gridID, &gridOps ) == RESH_CLOSED )
{
Warning("%s", "Operation not executed.");
return;
}
gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
grid_t* gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
grid_check_ptr(gridID, gridptr);
memcpy(gridptr->uuid, uuid, 16);
return;
}
/*
......@@ -4371,9 +4371,7 @@ The function @func{gridInqUUID} returns the UUID to an unstructured grid.
*/
void gridInqUUID(int gridID, char *uuid)
{
grid_t *gridptr;
gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
grid_t* gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
grid_check_ptr(gridID, gridptr);
......
......@@ -57,6 +57,7 @@ typedef struct {
int np; /* number of parallels between a pole and the equator */
int locked;
int lcomplex;
int hasdims;
char xname[CDI_MAX_NAME];
char yname[CDI_MAX_NAME];
char xlongname[CDI_MAX_NAME];
......
......@@ -1332,7 +1332,7 @@ int checkGridName(int type, char *axisname, int fileID, int vlistID, int gridID,
#if defined (HAVE_LIBNETCDF)
static
void cdfDefXaxis(stream_t *streamptr, int gridID)
void cdfDefXaxis(stream_t *streamptr, int gridID, int ndims)
{
char units[CDI_MAX_NAME];
char longname[CDI_MAX_NAME];
......@@ -1343,7 +1343,7 @@ void cdfDefXaxis(stream_t *streamptr, int gridID)
int gridID0, gridtype0, gridindex;
int dimID = UNDEFID;
int dimIDs[2];
int ngrids;
int ngrids = 0;
int fileID;
int dimlen, dimlen0;
size_t len;
......@@ -1357,7 +1357,7 @@ void cdfDefXaxis(stream_t *streamptr, int gridID)
vlistID = streamptr->vlistID;
fileID = streamptr->fileID;
ngrids = vlistNgrids(vlistID);
if ( ndims ) ngrids = vlistNgrids(vlistID);
dimlen = gridInqXsize(gridID);
gridindex = vlistGridIndex(vlistID, gridID);
......@@ -1402,22 +1402,25 @@ void cdfDefXaxis(stream_t *streamptr, int gridID)
{
int status;
status = checkGridName('V', axisname, fileID, vlistID, gridID, ngrids, 'X');
if ( status == 0 )
if ( status == 0 && ndims )
status = checkGridName('D', axisname, fileID, vlistID, gridID, ngrids, 'X');
if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
cdf_def_dim(fileID, axisname, dimlen, &dimID);
if ( gridInqXboundsPtr(gridID) || gridInqYboundsPtr(gridID) )
if ( ndims )
{
if ( nc_inq_dimid(fileID, "nb2", &nvdimID) != NC_NOERR )
cdf_def_dim(fileID, "nb2", nvertex, &nvdimID);
cdf_def_dim(fileID, axisname, dimlen, &dimID);
if ( gridInqXboundsPtr(gridID) || gridInqYboundsPtr(gridID) )
{
if ( nc_inq_dimid(fileID, "nb2", &nvdimID) != NC_NOERR )
cdf_def_dim(fileID, "nb2", nvertex, &nvdimID);
}
}
if ( gridInqXvalsPtr(gridID) )
{
cdf_def_var(fileID, axisname, (nc_type) xtype, 1, &dimID, &ncvarid);
cdf_def_var(fileID, axisname, (nc_type) xtype, ndims, &dimID, &ncvarid);
if ( (len = strlen(stdname)) )
cdf_put_att_text(fileID, ncvarid, "standard_name", len, stdname);
......@@ -1450,6 +1453,8 @@ void cdfDefXaxis(stream_t *streamptr, int gridID)
if ( ncvarid != UNDEFID ) cdf_put_var_double(fileID, ncvarid, gridInqXvalsPtr(gridID));
if ( ncbvarid != UNDEFID ) cdf_put_var_double(fileID, ncbvarid, gridInqXboundsPtr(gridID));
if ( ndims == 0 ) streamptr->ncxvarID[gridindex] = ncvarid;
}
streamptr->xdimID[gridindex] = dimID;
......@@ -1458,7 +1463,7 @@ void cdfDefXaxis(stream_t *streamptr, int gridID)
#if defined (HAVE_LIBNETCDF)
static
void cdfDefYaxis(stream_t *streamptr, int gridID)
void cdfDefYaxis(stream_t *streamptr, int gridID, int ndims)
{
char units[CDI_MAX_NAME];
char longname[CDI_MAX_NAME];
......@@ -1469,7 +1474,7 @@ void cdfDefYaxis(stream_t *streamptr, int gridID)
int gridID0, gridtype0, gridindex;
int dimID = UNDEFID;
int dimIDs[2];
int ngrids;
int ngrids = 0;
int fileID;
int dimlen, dimlen0;
size_t len;
......@@ -1483,7 +1488,7 @@ void cdfDefYaxis(stream_t *streamptr, int gridID)
vlistID = streamptr->vlistID;
fileID = streamptr->fileID;
ngrids = vlistNgrids(vlistID);
if ( ndims ) ngrids = vlistNgrids(vlistID);
dimlen = gridInqYsize(gridID);
gridindex = vlistGridIndex(vlistID, gridID);
......@@ -1528,22 +1533,25 @@ void cdfDefYaxis(stream_t *streamptr, int gridID)
{
int status;
status = checkGridName('V', axisname, fileID, vlistID, gridID, ngrids, 'Y');
if ( status == 0 )
if ( status == 0 && ndims )
status = checkGridName('D', axisname, fileID, vlistID, gridID, ngrids, 'Y');
if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
cdf_def_dim(fileID, axisname, dimlen, &dimID);
if ( gridInqXboundsPtr(gridID) || gridInqYboundsPtr(gridID) )
if ( ndims )
{
if ( nc_inq_dimid(fileID, "nb2", &nvdimID) != NC_NOERR )
cdf_def_dim(fileID, "nb2", nvertex, &nvdimID);
cdf_def_dim(fileID, axisname, dimlen, &dimID);
if ( gridInqXboundsPtr(gridID) || gridInqYboundsPtr(gridID) )
{
if ( nc_inq_dimid(fileID, "nb2", &nvdimID) != NC_NOERR )
cdf_def_dim(fileID, "nb2", nvertex, &nvdimID);
}
}
if ( gridInqYvalsPtr(gridID) )
{
cdf_def_var(fileID, axisname, (nc_type) xtype, 1, &dimID, &ncvarid);
cdf_def_var(fileID, axisname, (nc_type) xtype, ndims, &dimID, &ncvarid);
if ( (len = strlen(stdname)) )
cdf_put_att_text(fileID, ncvarid, "standard_name", len, stdname);
......@@ -1576,6 +1584,8 @@ void cdfDefYaxis(stream_t *streamptr, int gridID)
if ( ncvarid != UNDEFID ) cdf_put_var_double(fileID, ncvarid, gridInqYvalsPtr(gridID));
if ( ncbvarid != UNDEFID ) cdf_put_var_double(fileID, ncbvarid, gridInqYboundsPtr(gridID));
if ( ndims == 0 ) streamptr->ncyvarID[gridindex] = ncvarid;
}
streamptr->ydimID[gridindex] = dimID;
......@@ -2682,13 +2692,13 @@ void cdfDefGrid(stream_t *streamptr, int gridID)
int lx = 0, ly = 0;
if ( gridInqXsize(gridID) > 0 /*&& gridInqXvals(gridID, NULL) > 0*/ )
{
cdfDefXaxis(streamptr, gridID);
cdfDefXaxis(streamptr, gridID, 1);
lx = 1;
}
if ( gridInqYsize(gridID) > 0 /*&& gridInqYvals(gridID, NULL) > 0*/ )
{
cdfDefYaxis(streamptr, gridID);
cdfDefYaxis(streamptr, gridID, 1);
ly = 1;
}
......@@ -2697,8 +2707,12 @@ void cdfDefGrid(stream_t *streamptr, int gridID)
}
else
{
if ( gridInqXsize(gridID) > 0 ) cdfDefXaxis(streamptr, gridID);
if ( gridInqYsize(gridID) > 0 ) cdfDefYaxis(streamptr, gridID);
int ndims = 1;
if ( gridtype == GRID_LONLAT && size == 1 && gridInqHasDims(gridID) == FALSE )
ndims = 0;
if ( gridInqXsize(gridID) > 0 ) cdfDefXaxis(streamptr, gridID, ndims);
if ( gridInqYsize(gridID) > 0 ) cdfDefYaxis(streamptr, gridID, ndims);
}
if ( gridIsRotated(gridID) ) cdfDefPole(streamptr, gridID);
......@@ -2732,8 +2746,8 @@ void cdfDefGrid(stream_t *streamptr, int gridID)
}
else if ( gridtype == GRID_SINUSOIDAL || gridtype == GRID_LAEA || gridtype == GRID_LCC2 )
{
cdfDefXaxis(streamptr, gridID);
cdfDefYaxis(streamptr, gridID);
cdfDefXaxis(streamptr, gridID, 1);
cdfDefYaxis(streamptr, gridID, 1);
cdfDefMapping(streamptr, gridID);
}
......@@ -3058,8 +3072,7 @@ int cdfDefVar(stream_t *streamptr, int varID)
cdf_put_att_int(fileID, ncvarid, "table", NC_INT, 1, &tablenum);
}
if ( gridtype != GRID_GENERIC && gridtype != GRID_LONLAT &&
gridtype != GRID_CURVILINEAR )
if ( gridtype != GRID_GENERIC && gridtype != GRID_LONLAT && gridtype != GRID_CURVILINEAR )
{
len = strlen(gridNamePtr(gridtype));
if ( len > 0 )
......@@ -3091,6 +3104,28 @@ int cdfDefVar(stream_t *streamptr, int varID)
{
cdf_put_att_text(fileID, ncvarid, "coordinates", 9, "tlon tlat" );
}
else if ( gridtype == GRID_LONLAT && xid == UNDEFID && yid == UNDEFID && gridsize == 1 )
{
char coordinates[CDI_MAX_NAME] = "";
int ncxvarID, ncyvarID;
int gridindex;
size_t len;
gridindex = vlistGridIndex(vlistID, gridID);
ncxvarID = streamptr->ncxvarID[gridindex];
ncyvarID = streamptr->ncyvarID[gridindex];
if ( ncxvarID != CDI_UNDEFID )
cdf_inq_varname(fileID, ncxvarID, coordinates);
len = strlen(coordinates);
if ( ncyvarID != CDI_UNDEFID )
{
if ( len ) coordinates[len++] = ' ';
cdf_inq_varname(fileID, ncyvarID, coordinates+len);
}
len = strlen(coordinates);
if ( len )
cdf_put_att_text(fileID, ncvarid, "coordinates", len, coordinates);
}
else if ( gridtype == GRID_UNSTRUCTURED || gridtype == GRID_CURVILINEAR )
{
char coordinates[CDI_MAX_NAME] = "";
......@@ -6260,6 +6295,8 @@ void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
gridindex = vlistGridIndex(vlistID, ncvars[ncvarid].gridID);
streamptr->xdimID[gridindex] = xdimid;
streamptr->ydimID[gridindex] = ydimid;
if ( xdimid == -1 && ydimid == -1 && grid.size == 1 )
gridDefHasDims(ncvars[ncvarid].gridID, FALSE);
if ( CDI_Debug )
Message("gridID %d %d %s", ncvars[ncvarid].gridID, ncvarid, ncvars[ncvarid].name);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment