vs2013+NetCDF三维数据的读取方法

来源:互联网 发布:centos配置net snmp 编辑:程序博客网 时间:2024/05/14 15:03

一、环境:win7+vs2013+NetCDF4.4.2

二、测试数据样例
测试的是读取三维经度是的数据,该数据个数总共有120*241*480个,我这里的120指的是时间索引数,241和480指经纬度。
图1如下:
说明:
1、时间、经度、纬度个数。
2、scale_factor:缩放因子。
3、add_offset:截距值。
4、_FillValue:填充值。
5、missing_value:无效值。
6、units:温度单位。
这里写图片描述

数据表:
这里写图片描述

三、测试效果
这里写图片描述

四、核心代码

1、主要函数接口

/// 根据varname获得其对应的3维以上维数组数据:例如温度点。目前仅测试3维数据的读取没有问题,一维二维的读取使用该接口有问题,还需要完善    /// 参数说明:    /// varname:变量名字;scaleFactor:缩放因子;addOffset:截距值;missingValue:无效值;timeName:时间变量名称;levelName:层次变量名称;dataVector:读取的数据    /// timeName:一般三维数据时使用    /// levelName:一般是四维数据时使用,如果不是四维的话直接填充空值即可用到的成员变量:int m_ncid;函数接口:int  ReadNCFile::getVarDataArrayManyD(const char *varName, const char *scaleFactor, const char *addOffset, const char *missingValue, const char *timeName, const char *levelName, vector<float> &dataVector){    int ret = 0;    int varid = 0;    if (ret = nc_inq_varid(m_ncid, varName, &varid))        ERR(ret);    //获取对应变量的维度    int dimsCount = 0;    if (ret = nc_inq_varndims(m_ncid, varid, &dimsCount))        ERR(ret);    //获取每一维的长度    int *dimidsp = new int[dimsCount];    nc_inq_vardimid(m_ncid, varid, dimidsp);    size_t* dimLenp = new size_t[dimsCount];    for (int i = 0; i < dimsCount; ++i)    {        nc_inq_dimlen(m_ncid, dimidsp[i], &dimLenp[i]);    }    size_t* startp = new size_t[dimsCount];    size_t* countp = new size_t[dimsCount];    int nSizeX = 0;    int nSizeY = 0;    //至少是一维数据    nSizeX = dimLenp[dimsCount - 1];    startp[dimsCount - 1] = 0;    countp[dimsCount - 1] = nSizeX;    //如果大于一维    if (dimsCount > 1)    {        nSizeY = dimLenp[dimsCount - 2];        startp[dimsCount - 2] = 0;        countp[dimsCount - 2] = nSizeY;    }    //如果大于二维    if (dimsCount == 3)    {        int dimLevelid = 0;        size_t dimLevel = 0;        int levelFlag = nc_inq_dimid(m_ncid, timeName, &dimLevelid);        nc_inq_dimlen(m_ncid, dimLevelid, &dimLevel);        int dimTimeid = 0;        size_t dimTime = 0;        int timeFlag = nc_inq_dimid(m_ncid, levelName, &dimTimeid);        nc_inq_dimlen(m_ncid, dimTimeid, &dimTime);        if (dimLevel > 0 && levelFlag == 0)        {            startp[0] = m_nLevel;        }        else if (dimTime > 0 && timeFlag == 0)        {            startp[0] = m_nTime;        }        else        {            startp[0] = 0;        }        countp[0] = 1;//指定取几个时次或层次的数据    }    else if (dimsCount == 4)    {        startp[0] = 0;//指定从第几个时次取数据        startp[1] = 1;//指定从第几个层次取数据        countp[0] = 1;//指定取几个时次的数据        countp[1] = 1;//指定取几个层次的数据    }    //Read the data.    dataVector.resize(nSizeX * nSizeY);    if (ret = nc_get_vara_float(m_ncid, varid, &startp[0], &countp[0], &dataVector[0]))        ERR(ret);    if (scaleFactor != "" || addOffset != "" || missingValue != "")    {        float addOffsetNum;// 截距值        float scaleFactorNum;//缩放因子        float missingValueNum;//无效值        //获取变量的一些属性信息        if ((ret = nc_get_att_float(m_ncid, varid, scaleFactor, &scaleFactorNum)))            ERR(ret);        if ((ret = nc_get_att_float(m_ncid, varid, addOffset, &addOffsetNum)))            ERR(ret);        if ((ret = nc_get_att_float(m_ncid, varid, missingValue, &missingValueNum)))            ERR(ret);        for (int i = 0; i < dataVector.size(); ++i)        {            if (dataVector[i] != missingValueNum)            {                dataVector[i] = dataVector[i] * scaleFactorNum + addOffsetNum;            }        }    }}

2、测试核心代码

vector<float> dataArray;pTempFile->getVarDataArrayManyD("sst", "scale_factor", "add_offset", "missing_value","", "time", dataArray);vector<float>::iterator iterData;for (iterData = dataArray.begin(); iterData != dataArray.end();){    static int flag = 0;    flag++;        float tempdata = *iterData;        cout << "tempdata=" << tempdata << endl;        if (flag == 30)            break;}

说明:根据自己的实际情况请参考使用,更多问题请参考博客中的其他文章。

原创粉丝点击