Commit 90e520b8 authored by Uwe Schulzweida's avatar Uwe Schulzweida
Browse files

Added support for CDI_KEY_UVRELATIVETOGRID.

parent 15ba64ee
...@@ -802,6 +802,7 @@ size_t gridInqYCvals(int gridID, char *ycvals[]); ...@@ -802,6 +802,7 @@ size_t gridInqYCvals(int gridID, char *ycvals[]);
#define CDI_KEY_GRIB2LOCALSECTIONNUMBER 818 // GRIB2 grib2LocalSectionNumber #define CDI_KEY_GRIB2LOCALSECTIONNUMBER 818 // GRIB2 grib2LocalSectionNumber
#define CDI_KEY_SECTION2PADDINGLENGTH 819 // GRIB2 length of section2Padding #define CDI_KEY_SECTION2PADDINGLENGTH 819 // GRIB2 length of section2Padding
#define CDI_KEY_SECTION2PADDING 820 // GRIB2 section2Padding #define CDI_KEY_SECTION2PADDING 820 // GRIB2 section2Padding
#define CDI_KEY_UVRELATIVETOGRID 821 // GRIB uvRelativeToGrid
// cdiDefKeyInt: Define an integer value from a key of a CDI variable // cdiDefKeyInt: Define an integer value from a key of a CDI variable
int cdiDefKeyInt(int cdiID, int varID, int key, int value); int cdiDefKeyInt(int cdiID, int varID, int key, int value);
......
...@@ -764,8 +764,9 @@ void gribapiGetGridGeneric(grib_handle *gh, grid_t *grid, size_t numberOfPoints) ...@@ -764,8 +764,9 @@ void gribapiGetGridGeneric(grib_handle *gh, grid_t *grid, size_t numberOfPoints)
} }
//TODO: Simplify by use of the convenience functions (gribGetLong(), gribGetLongDefault(), etc.). //TODO: Simplify by use of the convenience functions (gribGetLong(), gribGetLongDefault(), etc.).
void gribapiGetGrid(grib_handle *gh, grid_t *grid) bool gribapiGetGrid(grib_handle *gh, grid_t *grid)
{ {
bool uvRelativeToGrid = false;
const long editionNumber = gribEditionNumber(gh); const long editionNumber = gribEditionNumber(gh);
int gridtype = gribapiGetGridType(gh); int gridtype = gribapiGetGridType(gh);
int projtype = (gridtype == GRID_PROJECTION && gribapiGetIsRotated(gh)) ? CDI_PROJ_RLL : CDI_UNDEFID; int projtype = (gridtype == GRID_PROJECTION && gribapiGetIsRotated(gh)) ? CDI_PROJ_RLL : CDI_UNDEFID;
...@@ -834,6 +835,7 @@ void gribapiGetGrid(grib_handle *gh, grid_t *grid) ...@@ -834,6 +835,7 @@ void gribapiGetGrid(grib_handle *gh, grid_t *grid)
GRIB_CHECK(grib_get_long(gh, "uvRelativeToGrid", &temp), 0); GRIB_CHECK(grib_get_long(gh, "uvRelativeToGrid", &temp), 0);
assert(temp == 0 || temp == 1); assert(temp == 0 || temp == 1);
grid->uvRelativeToGrid = (bool)temp; grid->uvRelativeToGrid = (bool)temp;
uvRelativeToGrid = (bool)temp;
} }
if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_LONLAT || gridtype == GRID_PROJECTION ) if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_LONLAT || gridtype == GRID_PROJECTION )
...@@ -863,14 +865,16 @@ void gribapiGetGrid(grib_handle *gh, grid_t *grid) ...@@ -863,14 +865,16 @@ void gribapiGetGrid(grib_handle *gh, grid_t *grid)
Message("(param,ltype,level) = (%3d,%3d,%4d); Scanning mode = %02d -> bits:(%1d.%1d.%1d)*32; uvRelativeToGrid = %02d",\ Message("(param,ltype,level) = (%3d,%3d,%4d); Scanning mode = %02d -> bits:(%1d.%1d.%1d)*32; uvRelativeToGrid = %02d",\
(int)paramId, (int)levelTypeId, (int)levelId, (int)paramId, (int)levelTypeId, (int)levelId,
grid->scanningMode,grid->jPointsAreConsecutive, grid->scanningMode,grid->jPointsAreConsecutive,
grid->jScansPositively,grid->iScansNegatively, grid->jScansPositively, grid->iScansNegatively,
grid->uvRelativeToGrid); uvRelativeToGrid);
} }
#endif //HIRLAM_EXTENSIONS #endif //HIRLAM_EXTENSIONS
} }
grid->type = gridtype; grid->type = gridtype;
grid->projtype = projtype; grid->projtype = projtype;
return uvRelativeToGrid;
} }
#endif #endif
/* /*
......
...@@ -31,7 +31,7 @@ int gribapiGetTsteptype(grib_handle *gh); ...@@ -31,7 +31,7 @@ int gribapiGetTsteptype(grib_handle *gh);
int gribGetDatatype(grib_handle* gribHandle); int gribGetDatatype(grib_handle* gribHandle);
int gribapiGetParam(grib_handle *gh); int gribapiGetParam(grib_handle *gh);
int gribapiGetGridType(grib_handle *gh); int gribapiGetGridType(grib_handle *gh);
void gribapiGetGrid(grib_handle *gh, grid_t *grid); bool gribapiGetGrid(grib_handle *gh, grid_t *grid);
size_t gribapiGetGridsize(grib_handle *gh); size_t gribapiGetGridsize(grib_handle *gh);
......
...@@ -240,8 +240,9 @@ int cgribexGetTsteptype(int timerange) ...@@ -240,8 +240,9 @@ int cgribexGetTsteptype(int timerange)
} }
static static
void cgribexGetGrid(stream_t *streamptr, int *isec2, int *isec4, grid_t *grid, int iret) bool cgribexGetGrid(stream_t *streamptr, int *isec2, int *isec4, grid_t *grid, int iret)
{ {
bool uvRelativeToGrid = false;
bool compyinc = true; bool compyinc = true;
int gridtype = cgribexGetGridType(isec2); int gridtype = cgribexGetGridType(isec2);
int projtype = (gridtype == GRID_PROJECTION && cgribexGetIsRotated(isec2)) ? CDI_PROJ_RLL : CDI_UNDEFID; int projtype = (gridtype == GRID_PROJECTION && cgribexGetIsRotated(isec2)) ? CDI_PROJ_RLL : CDI_UNDEFID;
...@@ -268,8 +269,7 @@ void cgribexGetGrid(stream_t *streamptr, int *isec2, int *isec4, grid_t *grid, i ...@@ -268,8 +269,7 @@ void cgribexGetGrid(stream_t *streamptr, int *isec2, int *isec4, grid_t *grid, i
if ( gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN || projtype == CDI_PROJ_RLL ) if ( gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN || projtype == CDI_PROJ_RLL )
{ {
const bool ijDirectionIncrementGiven = gribbyte_get_bit(ISEC2_ResFlag, 1); const bool ijDirectionIncrementGiven = gribbyte_get_bit(ISEC2_ResFlag, 1);
const bool uvRelativeToGrid = gribbyte_get_bit(ISEC2_ResFlag, 5); uvRelativeToGrid = gribbyte_get_bit(ISEC2_ResFlag, 5);
if ( uvRelativeToGrid ) grid->uvRelativeToGrid = 1;
const size_t nvalues = (size_t) ISEC4_NumValues; const size_t nvalues = (size_t) ISEC4_NumValues;
const size_t nlon = (size_t) ISEC2_NumLon; const size_t nlon = (size_t) ISEC2_NumLon;
...@@ -352,8 +352,7 @@ void cgribexGetGrid(stream_t *streamptr, int *isec2, int *isec4, grid_t *grid, i ...@@ -352,8 +352,7 @@ void cgribexGetGrid(stream_t *streamptr, int *isec2, int *isec4, grid_t *grid, i
else if ( gridtype == GRID_GAUSSIAN_REDUCED ) else if ( gridtype == GRID_GAUSSIAN_REDUCED )
{ {
const bool ijDirectionIncrementGiven = gribbyte_get_bit(ISEC2_ResFlag, 1); const bool ijDirectionIncrementGiven = gribbyte_get_bit(ISEC2_ResFlag, 1);
const bool uvRelativeToGrid = gribbyte_get_bit(ISEC2_ResFlag, 5); uvRelativeToGrid = gribbyte_get_bit(ISEC2_ResFlag, 5);
if ( uvRelativeToGrid ) grid->uvRelativeToGrid = 1;
grid->np = ISEC2_NumPar; grid->np = ISEC2_NumPar;
grid->size = (size_t)ISEC4_NumValues; grid->size = (size_t)ISEC4_NumValues;
grid->rowlon = ISEC2_RowLonPtr; grid->rowlon = ISEC2_RowLonPtr;
...@@ -394,8 +393,7 @@ void cgribexGetGrid(stream_t *streamptr, int *isec2, int *isec4, grid_t *grid, i ...@@ -394,8 +393,7 @@ void cgribexGetGrid(stream_t *streamptr, int *isec2, int *isec4, grid_t *grid, i
} }
else if ( projtype == CDI_PROJ_LCC ) else if ( projtype == CDI_PROJ_LCC )
{ {
const bool uvRelativeToGrid = gribbyte_get_bit(ISEC2_ResFlag, 5); uvRelativeToGrid = gribbyte_get_bit(ISEC2_ResFlag, 5);
if ( uvRelativeToGrid ) grid->uvRelativeToGrid = 1;
const size_t nvalues = (size_t) ISEC4_NumValues; const size_t nvalues = (size_t) ISEC4_NumValues;
const size_t nlon = (size_t) ISEC2_NumLon; const size_t nlon = (size_t) ISEC2_NumLon;
...@@ -443,6 +441,10 @@ void cgribexGetGrid(stream_t *streamptr, int *isec2, int *isec4, grid_t *grid, i ...@@ -443,6 +441,10 @@ void cgribexGetGrid(stream_t *streamptr, int *isec2, int *isec4, grid_t *grid, i
grid->type = gridtype; grid->type = gridtype;
grid->projtype = projtype; grid->projtype = projtype;
if ( uvRelativeToGrid ) grid->uvRelativeToGrid = 1;
return uvRelativeToGrid;
} }
static static
...@@ -466,6 +468,8 @@ void cgribexAddRecord(stream_t *streamptr, cgribexrec_t *cgribexp, int param, si ...@@ -466,6 +468,8 @@ void cgribexAddRecord(stream_t *streamptr, cgribexrec_t *cgribexp, int param, si
double *fsec3 = cgribexp->fsec3; double *fsec3 = cgribexp->fsec3;
int datatype = (ISEC4_NumBits > 0 && ISEC4_NumBits <= 32) ? ISEC4_NumBits : CDI_DATATYPE_PACK; int datatype = (ISEC4_NumBits > 0 && ISEC4_NumBits <= 32) ? ISEC4_NumBits : CDI_DATATYPE_PACK;
if ( datatype > 32 ) datatype = CDI_DATATYPE_PACK32;
if ( datatype < 0 ) datatype = CDI_DATATYPE_PACK;
int varID; int varID;
int levelID = 0; int levelID = 0;
...@@ -492,7 +496,7 @@ void cgribexAddRecord(stream_t *streamptr, cgribexrec_t *cgribexp, int param, si ...@@ -492,7 +496,7 @@ void cgribexAddRecord(stream_t *streamptr, cgribexrec_t *cgribexp, int param, si
record->tsteptype = (short)tsteptype; record->tsteptype = (short)tsteptype;
grid_t *gridptr = (grid_t*) Malloc(sizeof(*gridptr)); grid_t *gridptr = (grid_t*) Malloc(sizeof(*gridptr));
cgribexGetGrid(streamptr, isec2, isec4, gridptr, iret); const bool uvRelativeToGrid = cgribexGetGrid(streamptr, isec2, isec4, gridptr, iret);
struct addIfNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, gridptr, 0); struct addIfNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, gridptr, 0);
int gridID = gridAdded.Id; int gridID = gridAdded.Id;
...@@ -514,9 +518,9 @@ void cgribexAddRecord(stream_t *streamptr, cgribexrec_t *cgribexp, int param, si ...@@ -514,9 +518,9 @@ void cgribexAddRecord(stream_t *streamptr, cgribexrec_t *cgribexp, int param, si
} }
else if ( gridptr->projtype == CDI_PROJ_LCC ) else if ( gridptr->projtype == CDI_PROJ_LCC )
{ {
double a = 6367470., rf = 0; const bool earthIsOblate = gribbyte_get_bit(ISEC2_ResFlag, 2);
bool earthIsOblate = gribbyte_get_bit(ISEC2_ResFlag, 2); const double a = earthIsOblate ? 6378160. : 6367470.;
if ( earthIsOblate ) { a = 6378160.; rf = 297.0; } const double rf = earthIsOblate ? 297.0 : 0;
const double xval_0 = ISEC2_FirstLon * 0.001; const double xval_0 = ISEC2_FirstLon * 0.001;
const double yval_0 = ISEC2_FirstLat * 0.001; const double yval_0 = ISEC2_FirstLat * 0.001;
const double lon_0 = ISEC2_Lambert_Lov * 0.001; const double lon_0 = ISEC2_Lambert_Lov * 0.001;
...@@ -552,18 +556,17 @@ void cgribexAddRecord(stream_t *streamptr, cgribexrec_t *cgribexp, int param, si ...@@ -552,18 +556,17 @@ void cgribexAddRecord(stream_t *streamptr, cgribexrec_t *cgribexp, int param, si
const bool lbounds = cgribexGetZaxisHasBounds(leveltype); const bool lbounds = cgribexGetZaxisHasBounds(leveltype);
if ( datatype > 32 ) datatype = CDI_DATATYPE_PACK32;
if ( datatype < 0 ) datatype = CDI_DATATYPE_PACK;
varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, 0, 0, varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, 0, 0,
datatype, &varID, &levelID, tsteptype, numavg, leveltype, -1, datatype, &varID, &levelID, tsteptype, numavg, leveltype, -1,
NULL, NULL, NULL, NULL, NULL, NULL, 0); NULL, NULL, NULL, NULL, NULL, NULL, 0);
record->varID = (short)varID; record->varID = (short)varID;
record->levelID = (short)levelID; record->levelID = (short)levelID;
varDefCompType(varID, comptype); varDefCompType(varID, comptype);
if ( uvRelativeToGrid ) varDefKeyInt(varID, CDI_KEY_UVRELATIVETOGRID, 1);
if ( ISEC1_LocalFLag ) if ( ISEC1_LocalFLag )
{ {
if ( ISEC1_CenterID == 78 && isec1[36] == 253 ) // DWD local extension if ( ISEC1_CenterID == 78 && isec1[36] == 253 ) // DWD local extension
...@@ -584,9 +587,9 @@ void cgribexAddRecord(stream_t *streamptr, cgribexrec_t *cgribexp, int param, si ...@@ -584,9 +587,9 @@ void cgribexAddRecord(stream_t *streamptr, cgribexrec_t *cgribexp, int param, si
if ( varInqInst(varID) == CDI_UNDEFID ) if ( varInqInst(varID) == CDI_UNDEFID )
{ {
const int center = ISEC1_CenterID; const int center = ISEC1_CenterID;
const int subcenter = ISEC1_SubCenterID; const int subcenter = ISEC1_SubCenterID;
int instID = institutInq(center, subcenter, NULL, NULL); int instID = institutInq(center, subcenter, NULL, NULL);
if ( instID == CDI_UNDEFID ) if ( instID == CDI_UNDEFID )
instID = institutDef(center, subcenter, NULL, NULL); instID = institutDef(center, subcenter, NULL, NULL);
varDefInst(varID, instID); varDefInst(varID, instID);
...@@ -1587,7 +1590,7 @@ void cgribexDefTime(int *isec1, int vdate, int vtime, int tsteptype, int numavg, ...@@ -1587,7 +1590,7 @@ void cgribexDefTime(int *isec1, int vdate, int vtime, int tsteptype, int numavg,
} }
static static
void cgribexDefGridRegular(int *isec2, double *fsec2, int gridID, int gridtype, bool gridIsRotated, bool gridIsCurvilinear) void cgribexDefGridRegular(int *isec2, double *fsec2, int gridID, int gridtype, bool gridIsRotated, bool gridIsCurvilinear, int uvRelativeToGrid)
{ {
if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_GAUSSIAN_REDUCED ) if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_GAUSSIAN_REDUCED )
ISEC2_GridType = GRIB1_GTYPE_GAUSSIAN; ISEC2_GridType = GRIB1_GTYPE_GAUSSIAN;
...@@ -1662,8 +1665,8 @@ void cgribexDefGridRegular(int *isec2, double *fsec2, int gridID, int gridtype, ...@@ -1662,8 +1665,8 @@ void cgribexDefGridRegular(int *isec2, double *fsec2, int gridID, int gridtype,
if ( ISEC2_LonIncr == 0 && ISEC2_LatIncr != 0 ) ISEC2_LonIncr = ISEC2_LatIncr; if ( ISEC2_LonIncr == 0 && ISEC2_LatIncr != 0 ) ISEC2_LonIncr = ISEC2_LatIncr;
ISEC2_ResFlag = 0; ISEC2_ResFlag = 0;
if ( ISEC2_LatIncr && ISEC2_LonIncr ) gribbyte_set_bit(&ISEC2_ResFlag, 1); if ( ISEC2_LatIncr && ISEC2_LonIncr ) gribbyte_set_bit(&ISEC2_ResFlag, 1);
if ( gridInqUvRelativeToGrid(gridID) ) gribbyte_set_bit(&ISEC2_ResFlag, 5); if ( uvRelativeToGrid > 0 ) gribbyte_set_bit(&ISEC2_ResFlag, 5);
if ( gridIsRotated ) if ( gridIsRotated )
{ {
...@@ -1682,7 +1685,7 @@ void cgribexDefGridRegular(int *isec2, double *fsec2, int gridID, int gridtype, ...@@ -1682,7 +1685,7 @@ void cgribexDefGridRegular(int *isec2, double *fsec2, int gridID, int gridtype,
} }
static static
void cgribexDefGridLambert(int *isec2, int gridID) void cgribexDefGridLambert(int *isec2, int gridID, int uvRelativeToGrid)
{ {
const int xsize = (int)gridInqXsize(gridID); const int xsize = (int)gridInqXsize(gridID);
const int ysize = (int)gridInqYsize(gridID); const int ysize = (int)gridInqYsize(gridID);
...@@ -1714,8 +1717,8 @@ void cgribexDefGridLambert(int *isec2, int gridID) ...@@ -1714,8 +1717,8 @@ void cgribexDefGridLambert(int *isec2, int gridID)
const bool earthIsOblate = (IS_EQUAL(a, 6378160.) && IS_EQUAL(rf, 297.)); const bool earthIsOblate = (IS_EQUAL(a, 6378160.) && IS_EQUAL(rf, 297.));
ISEC2_ResFlag = 0; ISEC2_ResFlag = 0;
if ( ISEC2_Lambert_dx && ISEC2_Lambert_dy ) gribbyte_set_bit(&ISEC2_ResFlag, 1); if ( ISEC2_Lambert_dx && ISEC2_Lambert_dy ) gribbyte_set_bit(&ISEC2_ResFlag, 1);
if ( earthIsOblate ) gribbyte_set_bit(&ISEC2_ResFlag, 2); if ( earthIsOblate ) gribbyte_set_bit(&ISEC2_ResFlag, 2);
if ( gridInqUvRelativeToGrid(gridID) ) gribbyte_set_bit(&ISEC2_ResFlag, 5); if ( uvRelativeToGrid > 0 ) gribbyte_set_bit(&ISEC2_ResFlag, 5);
ISEC2_ScanFlag = 0; ISEC2_ScanFlag = 0;
gribbyte_set_bit(&ISEC2_ScanFlag, 2); // South -> North gribbyte_set_bit(&ISEC2_ScanFlag, 2); // South -> North
...@@ -1764,7 +1767,7 @@ void cgribexDefGridGME(int *isec2, int gridID) ...@@ -1764,7 +1767,7 @@ void cgribexDefGridGME(int *isec2, int gridID)
} }
static static
void cgribexDefGrid(int *isec1, int *isec2, double *fsec2, int *isec4, int gridID) void cgribexDefGrid(int *isec1, int *isec2, double *fsec2, int *isec4, int gridID, int uvRelativeToGrid)
{ {
memset(isec2, 0, 16*sizeof(int)); memset(isec2, 0, 16*sizeof(int));
ISEC1_Sec2Or3Flag = 128; ISEC1_Sec2Or3Flag = 128;
...@@ -1784,12 +1787,12 @@ void cgribexDefGrid(int *isec1, int *isec2, double *fsec2, int *isec4, int gridI ...@@ -1784,12 +1787,12 @@ void cgribexDefGrid(int *isec1, int *isec2, double *fsec2, int *isec4, int gridI
case GRID_GAUSSIAN_REDUCED: case GRID_GAUSSIAN_REDUCED:
case GRID_TRAJECTORY: case GRID_TRAJECTORY:
{ {
cgribexDefGridRegular(isec2, fsec2, gridID, gridtype, gridIsRotated, gridIsCurvilinear); cgribexDefGridRegular(isec2, fsec2, gridID, gridtype, gridIsRotated, gridIsCurvilinear, uvRelativeToGrid);
break; break;
} }
case CDI_PROJ_LCC: case CDI_PROJ_LCC:
{ {
cgribexDefGridLambert(isec2, gridID); cgribexDefGridLambert(isec2, gridID, uvRelativeToGrid);
break; break;
} }
case GRID_SPECTRAL: case GRID_SPECTRAL:
...@@ -2074,9 +2077,12 @@ size_t cgribexEncode(int memtype, int varID, int levelID, int vlistID, int gridI ...@@ -2074,9 +2077,12 @@ size_t cgribexEncode(int memtype, int varID, int levelID, int vlistID, int gridI
const int datatype = vlistInqVarDatatype(vlistID, varID); const int datatype = vlistInqVarDatatype(vlistID, varID);
int uvRelativeToGrid = -1;
cdiInqKeyInt(vlistID, varID, CDI_KEY_UVRELATIVETOGRID, &uvRelativeToGrid);
cgribexDefParam(isec1, param); cgribexDefParam(isec1, param);
cgribexDefTime(isec1, vdate, vtime, tsteptype, numavg, vlistInqTaxis(vlistID)); cgribexDefTime(isec1, vdate, vtime, tsteptype, numavg, vlistInqTaxis(vlistID));
cgribexDefGrid(isec1, isec2, fsec2, isec4, gridID); cgribexDefGrid(isec1, isec2, fsec2, isec4, gridID, uvRelativeToGrid);
cgribexDefLevel(isec1, isec2, fsec2, zaxisID, levelID); cgribexDefLevel(isec1, isec2, fsec2, zaxisID, levelID);
cgribexDefEnsembleVar(isec1, vlistID, varID); cgribexDefEnsembleVar(isec1, vlistID, varID);
......
...@@ -595,12 +595,12 @@ void gribapiAddRecord(stream_t *streamptr, int param, grib_handle *gh, ...@@ -595,12 +595,12 @@ void gribapiAddRecord(stream_t *streamptr, int param, grib_handle *gh,
{ {
char stdname[CDI_MAX_NAME], longname[CDI_MAX_NAME], units[CDI_MAX_NAME]; char stdname[CDI_MAX_NAME], longname[CDI_MAX_NAME], units[CDI_MAX_NAME];
int vlistID = streamptr->vlistID; const int vlistID = streamptr->vlistID;
int tsID = streamptr->curTsID; const int tsID = streamptr->curTsID;
int recID = recordNewEntry(streamptr, tsID); const int recID = recordNewEntry(streamptr, tsID);
record_t *record = &streamptr->tsteps[tsID].records[recID]; record_t *record = &streamptr->tsteps[tsID].records[recID];
int tsteptype = gribapiGetTsteptype(gh); const int tsteptype = gribapiGetTsteptype(gh);
// numavg = ISEC1_AvgNum; // numavg = ISEC1_AvgNum;
int numavg = 0; int numavg = 0;
...@@ -622,16 +622,16 @@ void gribapiAddRecord(stream_t *streamptr, int param, grib_handle *gh, ...@@ -622,16 +622,16 @@ void gribapiAddRecord(stream_t *streamptr, int param, grib_handle *gh,
record->varname[sizeof(record->varname) - 1] = 0; record->varname[sizeof(record->varname) - 1] = 0;
grid_t *grid = (grid_t *)Malloc(sizeof(*grid)); grid_t *grid = (grid_t *)Malloc(sizeof(*grid));
gribapiGetGrid(gh, grid); const bool uvRelativeToGrid = gribapiGetGrid(gh, grid);
struct addIfNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, grid, 0); struct addIfNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, grid, 0);
int gridID = gridAdded.Id; const int gridID = gridAdded.Id;
if ( !gridAdded.isNew ) Free(grid); if ( !gridAdded.isNew ) Free(grid);
else if ( grid->projtype == CDI_PROJ_RLL ) gribapiDefProjRLL(gh, gridID); else if ( grid->projtype == CDI_PROJ_RLL ) gribapiDefProjRLL(gh, gridID);
else if ( grid->projtype == CDI_PROJ_LCC ) gribapiDefProjLCC(gh, gridID); else if ( grid->projtype == CDI_PROJ_LCC ) gribapiDefProjLCC(gh, gridID);
else if ( grid->projtype == CDI_PROJ_STERE ) gribapiDefProjSTERE(gh, gridID); else if ( grid->projtype == CDI_PROJ_STERE ) gribapiDefProjSTERE(gh, gridID);
int zaxistype = gribapiGetZaxisType(gribEditionNumber(gh), leveltype1); const int zaxistype = gribapiGetZaxisType(gribEditionNumber(gh), leveltype1);
switch (zaxistype) switch (zaxistype)
{ {
...@@ -641,7 +641,7 @@ void gribapiAddRecord(stream_t *streamptr, int param, grib_handle *gh, ...@@ -641,7 +641,7 @@ void gribapiAddRecord(stream_t *streamptr, int param, grib_handle *gh,
long lpar; long lpar;
GRIB_CHECK(grib_get_long(gh, "NV", &lpar), 0); GRIB_CHECK(grib_get_long(gh, "NV", &lpar), 0);
/* FIXME: assert(lpar >= 0) */ /* FIXME: assert(lpar >= 0) */
size_t vctsize = (size_t)lpar; const size_t vctsize = (size_t)lpar;
if ( vctsize > 0 ) if ( vctsize > 0 )
{ {
double *vctptr = (double *) Malloc(vctsize*sizeof(double)); double *vctptr = (double *) Malloc(vctsize*sizeof(double));
...@@ -697,11 +697,13 @@ void gribapiAddRecord(stream_t *streamptr, int param, grib_handle *gh, ...@@ -697,11 +697,13 @@ void gribapiAddRecord(stream_t *streamptr, int param, grib_handle *gh,
datatype, &varID, &levelID, tsteptype, numavg, leveltype1, leveltype2, datatype, &varID, &levelID, tsteptype, numavg, leveltype1, leveltype2,
varname, stdname, longname, units, tiles, &tile_index, perturbationNumber); varname, stdname, longname, units, tiles, &tile_index, perturbationNumber);
record->varID = (short)varID; record->varID = (short)varID;
record->levelID = (short)levelID; record->levelID = (short)levelID;
varDefCompType(varID, comptype); varDefCompType(varID, comptype);
if ( uvRelativeToGrid ) varDefKeyInt(varID, CDI_KEY_UVRELATIVETOGRID, 1);
gribapiGetKeys(gh, varID); gribapiGetKeys(gh, varID);
if (lread_additional_keys) if (lread_additional_keys)
...@@ -1883,7 +1885,7 @@ void gribapiDefTime(int editionNumber, int productDefinitionTemplate, int typeOf ...@@ -1883,7 +1885,7 @@ void gribapiDefTime(int editionNumber, int productDefinitionTemplate, int typeOf
} }
static static
void gribapiDefGridRegular(grib_handle *gh, int gridID, int gridtype, bool gridIsRotated, bool gridIsCurvilinear) void gribapiDefGridRegular(grib_handle *gh, int gridID, int gridtype, bool gridIsRotated, bool gridIsCurvilinear, int uvRelativeToGrid)
{ {
const char *mesg; const char *mesg;
size_t len; size_t len;
...@@ -1999,12 +2001,11 @@ void gribapiDefGridRegular(grib_handle *gh, int gridID, int gridtype, bool gridI ...@@ -1999,12 +2001,11 @@ void gribapiDefGridRegular(grib_handle *gh, int gridID, int gridtype, bool gridI
GRIB_CHECK(my_grib_set_double(gh, "angleOfRotation", angle), 0); GRIB_CHECK(my_grib_set_double(gh, "angleOfRotation", angle), 0);
} }
long uvRelativeToGrid = gridInqUvRelativeToGrid(gridID); if ( uvRelativeToGrid >= 0 ) GRIB_CHECK(my_grib_set_long(gh, "uvRelativeToGrid", uvRelativeToGrid), 0);
if ( uvRelativeToGrid ) GRIB_CHECK(my_grib_set_long(gh, "uvRelativeToGrid", uvRelativeToGrid), 0);
} }
static static
void gribapiDefGridLCC(grib_handle *gh, int editionNumber, int gridID) void gribapiDefGridLCC(grib_handle *gh, int editionNumber, int gridID, int uvRelativeToGrid)
{ {
long xsize = (long) gridInqXsize(gridID); long xsize = (long) gridInqXsize(gridID);
long ysize = (long) gridInqYsize(gridID); long ysize = (long) gridInqYsize(gridID);
...@@ -2036,8 +2037,7 @@ void gribapiDefGridLCC(grib_handle *gh, int editionNumber, int gridID) ...@@ -2036,8 +2037,7 @@ void gribapiDefGridLCC(grib_handle *gh, int editionNumber, int gridID)
GRIB_CHECK(my_grib_set_double(gh, "Latin2InDegrees", lat_2), 0); GRIB_CHECK(my_grib_set_double(gh, "Latin2InDegrees", lat_2), 0);
GRIB_CHECK(my_grib_set_long(gh, "projectionCentreFlag", projflag), 0); GRIB_CHECK(my_grib_set_long(gh, "projectionCentreFlag", projflag), 0);
long uvRelativeToGrid = gridInqUvRelativeToGrid(gridID); if ( uvRelativeToGrid >= 0 ) GRIB_CHECK(my_grib_set_long(gh, "uvRelativeToGrid", uvRelativeToGrid), 0);
if ( uvRelativeToGrid ) GRIB_CHECK(my_grib_set_long(gh, "uvRelativeToGrid", uvRelativeToGrid), 0);
long earthIsOblate = (IS_EQUAL(a, 6378160.) && IS_EQUAL(rf, 297.)); long earthIsOblate = (IS_EQUAL(a, 6378160.) && IS_EQUAL(rf, 297.));
if ( earthIsOblate ) GRIB_CHECK(my_grib_set_long(gh, "earthIsOblate", earthIsOblate), 0); if ( earthIsOblate ) GRIB_CHECK(my_grib_set_long(gh, "earthIsOblate", earthIsOblate), 0);
...@@ -2200,7 +2200,7 @@ void gribapiDefPackingType(grib_handle *gh, bool lieee, bool lspectral, bool lco ...@@ -2200,7 +2200,7 @@ void gribapiDefPackingType(grib_handle *gh, bool lieee, bool lspectral, bool lco
} }
static static
void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype, int datatype) void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype, int datatype, int uvRelativeToGrid)
{ {
// bitsPerValue have to be defined first (complex packing) // bitsPerValue have to be defined first (complex packing)
GRIB_CHECK(my_grib_set_long(gh, "bitsPerValue", (long)grbBitsPerValue(datatype)), 0); GRIB_CHECK(my_grib_set_long(gh, "bitsPerValue", (long)grbBitsPerValue(datatype)), 0);
...@@ -2237,12 +2237,12 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype ...@@ -2237,12 +2237,12 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype
case GRID_GAUSSIAN_REDUCED: case GRID_GAUSSIAN_REDUCED:
case GRID_TRAJECTORY: case GRID_TRAJECTORY:
{ {
gribapiDefGridRegular(gh, gridID, gridtype, gridIsRotated, gridIsCurvilinear); gribapiDefGridRegular(gh, gridID, gridtype, gridIsRotated, gridIsCurvilinear, uvRelativeToGrid);
break; break;
} }
case CDI_PROJ_LCC: case CDI_PROJ_LCC:
{ {
gribapiDefGridLCC(gh, editionNumber, gridID); gribapiDefGridLCC(gh, editionNumber, gridID, uvRelativeToGrid);
break; break;
} }
case CDI_PROJ_STERE: case CDI_PROJ_STERE:
...@@ -2607,7 +2607,7 @@ int gribapiGetScanningMode(grib_handle *gh) ...@@ -2607,7 +2607,7 @@ int gribapiGetScanningMode(grib_handle *gh)
void gribapiSetScanningMode(grib_handle *gh, int scanningMode) void gribapiSetScanningMode(grib_handle *gh, int scanningMode)
{ {
// 127: reserved for testing; generated test data will be in 64 scanning mode // 127: reserved for testing; generated test data will be in 64 scanning mode
//if (scanningMode== 127) scanningMode = 64; //if (scanningMode== 127) scanningMode = 64;
long iScansNegatively = (scanningMode & 128)/128; long iScansNegatively = (scanningMode & 128)/128;
...@@ -2633,21 +2633,6 @@ void gribapiSetScanningMode(grib_handle *gh, int scanningMode) ...@@ -2633,21 +2633,6 @@ void gribapiSetScanningMode(grib_handle *gh, int scanningMode)
} }
static
void gribapiSetUvRelativeToGrid(grib_handle *gh, int mode)
{
long uvRelativeToGridMode = mode;
long uvRelativeToGridModeOld;
GRIB_CHECK(grib_get_long(gh, "uvRelativeToGrid", &uvRelativeToGridModeOld), 0);
if (cdiDebugExt>=30)
printf("gribapiSetUvRelativeToGrid(): uvRelativeToGrid: %02d (old) => %02d (new); \n",(int)uvRelativeToGridModeOld,(int)uvRelativeToGridMode);
GRIB_CHECK(my_grib_set_long(gh, "uvRelativeToGrid", uvRelativeToGridMode), 0);
}
/* /*
TABLE 8. SCANNING MODE FLAG TABLE 8. SCANNING MODE FLAG
...@@ -3003,11 +2988,6 @@ void gribapiSetExtMode(grib_handle *gh, int gridID, size_t datasize, const doubl ...@@ -3003,11 +2988,6 @@ void gribapiSetExtMode(grib_handle *gh, int gridID, size_t datasize, const doubl
if (cdiDebugExt>=100) Message("Set ModeUvRelativeToGrid =>%d ( note grid has: %d)", cdiGribChangeModeUvRelativeToGrid.mode, gridInqUvRelativeToGrid(gridID)); if (cdiDebugExt>=100) Message("Set ModeUvRelativeToGrid =>%d ( note grid has: %d)", cdiGribChangeModeUvRelativeToGrid.mode, gridInqUvRelativeToGrid(gridID));
GRIB_CHECK(my_grib_set_long(gh, "uvRelativeToGrid", (long) cdiGribChangeModeUvRelativeToGrid.mode), 0); GRIB_CHECK(my_grib_set_long(gh, "uvRelativeToGrid", (long) cdiGribChangeModeUvRelativeToGrid.mode), 0);
} }
else
{
if (cdiDebugExt>=100) Message("Set ModeUvRelativeToGrid =>%d based on used grid", gridInqUvRelativeToGrid(gridID));
gribapiSetUvRelativeToGrid(gh, gridInqUvRelativeToGrid(gridID));
}
} }
} }
...@@ -3032,6 +3012,9 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI ...@@ -3032,6 +3012,9 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
int productDefinitionTemplate = 0; int productDefinitionTemplate = 0;
cdiInqKeyInt(vlistID, varID, CDI_KEY_PRODUCTDEFINITIONTEMPLATE, &productDefinitionTemplate); cdiInqKeyInt(vlistID, varID, CDI_KEY_PRODUCTDEFINITIONTEMPLATE, &productDefinitionTemplate);
int uvRelativeToGrid = -1;
cdiInqKeyInt(vlistID, varI