예제 #1
0
파일: NCtable.c 프로젝트: amiara/RGIS
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);
}
예제 #2
0
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);
}
예제 #3
0
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);
}
예제 #4
0
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);
}
예제 #5
0
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);
}