bool NCfieldGetFloat (NCfield_t *field,int id, double *val) { int intVal; double floatVal; switch (field->Type) { default: case NC_CHAR: goto NOVALUE; case NC_BYTE: case NC_SHORT: case NC_INT: if ((id < 0) && (id >= field->NRecords)) goto NOVALUE; intVal = ((int *) field->Data) [id]; if (intVal == field->FillValue.Int) goto NOVALUE; floatVal = (double) intVal * field->Scale + field->Offset; break; case NC_FLOAT: case NC_DOUBLE: if ((id < 0) && (id >= field->NRecords)) goto NOVALUE; floatVal = ((double *) field->Data) [id]; if (NCmathEqualValues (floatVal, field->FillValue.Float)) goto NOVALUE; floatVal = floatVal * field->Scale + field->Offset; break; } if (NCmathEqualValues (floatVal, field->MissingVal)) goto NOVALUE; *val = floatVal; return (true); NOVALUE: *val = FLOAT_NOVALUE; return (false); }
bool NCdsHandleGContGetFloat(const NCdsHandleGCont_t *gCont, NCreference_t *ref, double *val) { int i, obsNum = 0; double retVal, sumVal = 0.0, sumWeight = 0.0; if (ref->Num == 0) goto NOVALUE; retVal = gCont->Data[gCont->ColNum * ref->Idx[1] + ref->Idx[0]]; if (_NCdsHandleGContTestNodata(gCont, retVal) == false) { if (NCmathEqualValues(ref->Weight[0], 0.0)) { *val = retVal * gCont->Scale + gCont->Offset; return (true); } sumVal = retVal / ref->Weight[0]; sumWeight = 1.0 / ref->Weight[0]; obsNum = 1; } for (i = 1; i < ref->Num; i++) { retVal = gCont->Data[gCont->ColNum * ref->Idx[i * 2 + 1] + ref->Idx[i * 2]]; if (_NCdsHandleGContTestNodata(gCont, retVal)) continue; sumVal += retVal / ref->Weight[i]; sumWeight += 1.0 / ref->Weight[i]; obsNum++; } if (obsNum == 0) goto NOVALUE; *val = (sumVal / sumWeight) * gCont->Scale + gCont->Offset; return (true); NOVALUE: *val = FLOAT_NOVALUE; return (false); }
static bool _NCdsHandleGContTestNodata(const NCdsHandleGCont_t *gCont, double val) { switch (gCont->GType) { default: CMmsgPrint(CMmsgAppError, "Invalid data NetCDF type in: %s %d", __FILE__, __LINE__); break; case NC_BYTE: case NC_SHORT: case NC_INT: return ((gCont->MissingVal.Int == (int) val) || (gCont->FillValue.Int == (int) val) ? true : false); case NC_FLOAT: case NC_DOUBLE: return (NCmathEqualValues(gCont->MissingVal.Float, val) || NCmathEqualValues(gCont->FillValue.Float, val) ? true : false); } return (true); }
int NCdsHandleVPointReference(const NCdsHandleVPoint_t *point, const NCcoordinate_t *coord, NCreference_t *ref) { int idx[NCVPointNeighborNum], i, k, l, num; double minDist[NCVPointNeighborNum], dist; NCcoordinate_t pCoord; num = 0; for (i = 0; i < point->ItemNum; i++) { pCoord.X = point->XCoords[i]; pCoord.Y = point->YCoords[i]; if (NCmathEqualValues(pCoord.X, coord->X) && NCmathEqualValues(pCoord.Y, coord->Y)) { num = 1; idx[0] = i; break; } dist = NCmathCoordinateDistance(point->Projection, &pCoord, coord); if (num < NCVPointNeighborNum) num++; for (k = 0; k < num; k++) if (minDist[k] > dist) { for (l = num - 1; l > k; l--) { minDist[l] = minDist[l - 1]; idx[l] = idx[l - 1]; } minDist[k] = dist; idx[k] = i; break; } } if ((ref->Idx = (int *) calloc(num, sizeof(int))) == (int *) NULL) { CMmsgPrint(CMmsgSysError, "Memory allocation error in: %s %d", __FILE__, __LINE__); return (NCfailed); } for (k = 0; k < num; k++) { ref->Idx[k] = idx[k]; } if (num > 1) { if ((ref->Weight = (double *) calloc(num, sizeof(double))) == (double *) NULL) { CMmsgPrint(CMmsgSysError, "Memory allocation error in: %s %d", __FILE__, __LINE__); free(ref->Idx); NCreferenceInitialize(ref); return (NCfailed); } for (k = 0; k < num; k++) ref->Weight[k] = minDist[k]; } ref->Num = num; return (NCsucceeded); }
NCstate NCdsHandleGContDefine(NCdsHandleGCont_t *gCont, int *ncids, size_t n) { int status, varid, i; int missingInt, fillInt; double missingFloat, fillFloat, scale, offset; size_t unitlen, row, col; char unitstr[NC_MAX_NAME], gunitstr[NC_MAX_NAME]; gCont->Data = (double *) NULL; gCont->AuxData = (double *) NULL; gCont->ObsNum = (size_t *) NULL; gCont->MeanIds = gCont->MinIds = gCont->MaxIds = gCont->StdIds = (int *) NULL; if (n < 1) return (NCfailed); if (NCdsHandleGridDefine((NCdsHandleGrid_t *) gCont, ncids, n) == NCfailed) return (NCfailed); if (gCont->DataType != NCtypeGCont) { CMmsgPrint(CMmsgAppError, "Invalid grid data in: %s %d", __FILE__, __LINE__); NCdsHandleGridClear((NCdsHandleGrid_t *) gCont); return (NCfailed); } if (((gCont->MeanIds = (int *) calloc(n, sizeof(int))) == (int *) NULL) || ((gCont->MinIds = (int *) calloc(n, sizeof(int))) == (int *) NULL) || ((gCont->MaxIds = (int *) calloc(n, sizeof(int))) == (int *) NULL) || ((gCont->StdIds = (int *) calloc(n, sizeof(int))) == (int *) NULL) || ((gCont->Data = (double *) calloc(gCont->ColNum * gCont->RowNum, sizeof(double))) == (double *) NULL) || ((gCont->AuxData = (double *) calloc(gCont->ColNum * gCont->RowNum, sizeof(double))) == (double *) NULL) || ((gCont->ObsNum = (size_t *) calloc(gCont->ColNum * gCont->RowNum, sizeof(size_t))) == (size_t *) NULL)) { CMmsgPrint(CMmsgSysError, "Memory allocation error in: %s %d", __FILE__, __LINE__); if (gCont->MeanIds != (int *) NULL) free(gCont->MeanIds); if (gCont->MinIds != (int *) NULL) free(gCont->MinIds); if (gCont->MaxIds != (int *) NULL) free(gCont->MaxIds); if (gCont->StdIds != (int *) NULL) free(gCont->StdIds); NCdsHandleGridClear((NCdsHandleGrid_t *) gCont); return (NCfailed); } for (i = 0; i < n; ++i) gCont->MeanIds[i] = gCont->MinIds[i] = gCont->MaxIds[i] = gCont->StdIds[i] = NCundefined; for (i = 0; i < n; ++i) { switch (gCont->GType) { default: gCont->FillValue.Float = gCont->MissingVal.Float = FLOAT_NOVALUE; break; case NC_BYTE: case NC_SHORT: case NC_INT: if ((status = nc_get_att_int(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAFillValue, &fillInt)) != NC_NOERR) { if ((status = nc_get_att_int(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAMissingVal, &missingInt)) != NC_NOERR) missingInt = fillInt = INT_NOVALUE; else fillInt = missingInt; } else if ((status = nc_get_att_int(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAMissingVal, &missingInt)) != NC_NOERR) missingInt = fillInt; break; case NC_FLOAT: case NC_DOUBLE: if ((status = nc_get_att_double(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAFillValue, &fillFloat)) != NC_NOERR) { if ((status = nc_get_att_double(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAMissingVal, &missingFloat)) != NC_NOERR) missingFloat = fillFloat = FLOAT_NOVALUE; else fillFloat = missingFloat; } else if ((status = nc_get_att_double(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAMissingVal, &missingFloat)) != NC_NOERR) missingFloat = fillFloat; break; } if ((status = nc_get_att_double(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAScaleFactor, &scale)) != NC_NOERR) scale = 1.0; if ((status = nc_get_att_double(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAAddOffset, &offset)) != NC_NOERR) offset = 0.0; if (((status = nc_inq_attlen(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAUnits, &unitlen)) == NC_NOERR) && ((status = nc_get_att_text(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAUnits, unitstr)) == NC_NOERR)) unitstr[unitlen] = '\0'; if (i == 0) { if ((status == NC_NOERR) && (utScan(unitstr, &(gCont->GUnit)) == 0)) { gCont->DoGUnit = true; strcpy (gunitstr, unitstr); } else gCont->DoGUnit = false; switch (gCont->GType) { case NC_BYTE: case NC_SHORT: case NC_INT: gCont->FillValue.Int = fillInt; gCont->MissingVal.Int = missingInt; break; default: case NC_FLOAT: case NC_DOUBLE: gCont->FillValue.Float = fillFloat; gCont->MissingVal.Float = missingFloat; break; } gCont->Scale = scale; gCont->Offset = offset; } else { if (gCont->DoGUnit && ((status != NC_NOERR) || strcmp(unitstr, gunitstr) != 0)) { CMmsgPrint(CMmsgAppError, "Inconsistent data bundle (units) in: %s %d", __FILE__, __LINE__); return (NCfailed); } switch (gCont->GType) { case NC_BYTE: case NC_SHORT: case NC_INT: if ((gCont->FillValue.Int != fillInt) || (gCont->MissingVal.Int != missingInt)) { CMmsgPrint(CMmsgAppError, "Inconsistent data bundle (int fill value) in: %s %d", __FILE__, __LINE__); return (NCfailed); } break; default: case NC_FLOAT: case NC_DOUBLE: if ((NCmathEqualValues(gCont->FillValue.Float, fillFloat) == false) || (NCmathEqualValues(gCont->MissingVal.Float, missingFloat) == false)) { CMmsgPrint(CMmsgAppError, "Inconsistent bundle (float fill value) in: %s %d", __FILE__, __LINE__); return (NCfailed); } break; } if ((NCmathEqualValues(gCont->Scale, scale) == false) || (NCmathEqualValues(gCont->Offset, offset) == false)) { CMmsgPrint(CMmsgAppError, "Inconsistent bundle (scale and offset) in: %s %d", __FILE__, __LINE__); return (NCfailed); } } gCont->MeanIds[i] = nc_inq_varid(ncids[i], NCnameVAAverage, &varid) == NC_NOERR ? varid : NCundefined; gCont->MaxIds[i] = nc_inq_varid(ncids[i], NCnameVAMaximum, &varid) == NC_NOERR ? varid : NCundefined; gCont->MinIds[i] = nc_inq_varid(ncids[i], NCnameVAMinimum, &varid) == NC_NOERR ? varid : NCundefined; gCont->StdIds[i] = nc_inq_varid(ncids[i], NCnameVAStdDev, &varid) == NC_NOERR ? varid : NCundefined; } for (row = 0; row < gCont->RowNum; row++) for (col = 0; col < gCont->ColNum; col++) NCdsHandleGContSetFill(gCont, row, col); return (NCsucceeded); }