1.1 建工程文件
用vc6建立一个工程,使用动态链接库netcdf,然后把文件netcdfcpp.h
netcdfcpp.cpp ,ncvalues.h ncvalues.cpp,ncconfig.h包含到工程中。
1.2 NETCDF文件的读取
首先,定义一个NcFile类的对象,用NcFile类的构造函数直接对其初始化
NcFile(const char * path, FileMode = ReadOnly , … … );
path为文件的存储路径,FileMode为文件的打开方式,除了ReadOnly还有Write, New, Replace 等方式我们只是读文件可以选择ReadOnly,其他方式后面会介绍到,其他参数可以使用默认值,例如:
NcFile nc("G://File.nc", NcFile::ReadOnly);
使用nc.is_valid()来判断文件打开是否成功,以便进行下一步对NETCDF文件数据进行读取。
NETCDF文件主要是Dimensions, Variables, Attributes, Data 四个部分组成的,下面读出文件各个部分的内容。
Dimensions:
可以使用NETCDF 的成员函数num_dims()获得文件中的Dimensions的个数,然后用NcFile类的另一个成员函数get_dim(int id),或get_dim(NcToken name)---参数可以是id号(int),也可以是dim名字(NcToken),获得每一个文件的Dimensions,用NcDim类的成员函数id(),name(),size()可以依次读出每一个Dimensions的id号,名称,和size。
例如:
for (int i=0;i
{
String.Format(String+"dimid=%d name=%s length=%d/n",nc.get_dim(i)->id(),
nc.get_dim(i)->name(),nc.get_dim(i)->size());
}
利用一个for循环,依据dim的id号可以一次读出所有dim的信息
Variables:
同理用NETCDF 的成员函数num_vars()可以获得文件中Variables数量,用NcFile类get_var(int id)或 get_var(NcToken name)可以读出每一个文件中的Variables,也可以读出id,name这些信息,所不同的是,Variables还可以用num_dims()读出其所包含的Dimensions的个数,Variables还可以用get_dim(int id)读出其包含的Dimensions的相关信息,同时文件的Data信息也是通过Variables来操作的。
Data的读出:
首先,我们要根据Variables包含的每一个Dimensions的size计算出数据的大小,定义一个相应大小的数组,用来存放数据。
然后,用Variables的get(TYPE *array,long *num)第一个参数是刚才定义的存放数据的数组,第二个参数是自定义的一维数组,数组的元素用来存放每一维的size.一般用于多维数据。例如:
float rhs[50];
long array[3];
array[0]=1;
array[1]=5;
array[2]=10;
nc.get_var("rh")->get(rhs,array);
还可以用Variables的get( TYPE* vals,long edge0=0,long edge1=0,long edge2=0,long edge3=0,long edge4=0) const 第一个参数是存放数据的数组,后面的参数分别记录第1,2,3,4,5维的size,默认值为0,例如:
int n=nc.get_dim("lat")->size();
int lats[5];
nc.get_var("lat")->get(lats,n);
for (i=0;i<5;i++)
{
String.Format(String+" %d",lats[i]);
}
如果Variables中还包含说明的Attributes,可以使用函数get_att(int id),参数为Attributes的id,读出其Attributes。
例如:
String.Format("/natt:/n%s:%s/n",nc.get_var(0)->get_att(0)->name(),
nc.get_var(0)->get_att(0)->as_string(0));
Attributes:
Attributes可分为两种一种是整个文件的说明,即global attributes可以通过NcFile类的get_att(int id)函数来获得,参数为id号,例如:
String.Format(String+"/n%s: %s",nc.get_att(0)->name(),nc.get_att(0)->as_string(0));
还有一种是的说明,可以通过在Variables说明的方法获得,从读出的信息主要包括名称和相应的内容,可以通过name()和as_Type(long id),Type根据Attributes数据的类型来确定,如as_string(long id),as_int(long id)等,as_Type(long id)函数主要是用来取出每个Variables的内容。例子在Variables后面。
Data:
通过Variables我们已经把数据读出。
1.3 NETCDF文件的写入
和读文件时一样,首先要定义一个NcFile类的对象,如:
NcFile nc("G://File.nc", NcFile:: Replace);
用nc.is_valid()来判断文件打开是否成功,文件的打开方式我们可以选择New建立一个新的文件,用这种方式如果文件已经存在会返回错误,也可以用Write和Replace。选择Replace,如果文件已存在原文件就会被覆盖掉。用Write时文件必须已经存在,写入文件的数据会加在文件已存在数据的后面。
首先,建立一个NETCDF文件,需要写入的数据和刚才读出的数据是一样的,有Dimensions, Variables, Attributes, Data;
Dimensions:
用NcFile类的add_dim(NcToken name,long dimsize)成员函数加入Dimensions,如果size 为unlimited用NcFile类的add_dim(NcToken name)函数,NcFile类会自动把其size处理为unlimited。
例如:
nc.add_dim("lat",5);
nc.add_dim("time");//size 为unlimited时
Variables:
用NcFile类的add_var(NcToken name,NcType type,type dim1,type dim2,… …)成员函数加入Variables,dim1,…,dimn,为Variables中包含的Dimensions。
例如:
nc.add_var("lat",ncInt,nc.get_dim(0));//一个dim时
nc.add_var("rh",ncFloat,nc.get_dim("time"),
nc.get_dim("lat"),nc.get_dim("lon"));//多个dim时
Attributes:
整个文件的Attributes用NcFile的add_att(NcToken attname,Type value)函数Type根据加入Attributes的类型来判断;Variables可以用其成员函数add_att(attname, Type value)加入。
例如:
//写入文件的主要参数
nc.add_att("sourse","Fictional Model Output");
//写入单个变量的参数
nc.get_var(0)->add_att("long_name","Temperature");
Data:
先定义一个数组,把要写入文件的数据写入数组,用 Variables的函数put(TYPE *arr,const long *count)TYPE 为数据类型或Variable的函数put( TYPE* vals,long edge0=0,long edge1=0,long edge2=0,long edge3=0,long edge4=0) const,第一个参数是存放数据的数组,后面的参数分别记录第1,2,3,4,5维的size,默认值为0,例如:
int lats[5]={20,30,40,50,60}; //lat
nc.get_var("lat")->put(lats,5);
float rhss[50];
for (int i=0;i<1;i++)
for (int j=0;j<5;j++)
for (int k=0;k<10;k++)
{
rhss[i*5*10+j*10+k]= (float)(i*5*10+j*10+k+1)/100;
}
long count[3]; //由于rh有多个dim,要定义一个一维数组
count[0] = 1; //来说明其每一维的size
count[1] = 5;
count[2] = 10;
nc.get_var("rh")->put(rhss,count);