当前位置: 首页 > 工具软件 > NetCDF > 使用案例 >

NetCdf简介

龙玺
2023-12-01

NetCDF是由大气研究大学协会(UCAR) (http://my.unidata.ucar.edu)在Unidata Program中开发的。由于NetCDF是一种灵活的,自描述的,并能表达大量数组数据的格式,因此NetCDF在地球、海洋、大气科学中得到了广泛的应用。 一个NetCDF数据集的例子是20幅像元大小为30KM的北美地区影像,每一幅都有自己的高程级别。每一幅栅格图层中每个像元每小时测量一次、周期为一年的12个大气特征被记录了下来。因此,术语称为“多维数据”。 NetCDF的灵活性允许数据提供者和用户创建NetCDF模式来满足自己特殊的需求。这种灵活性的不利方面是有许多各种各样的NetCDF模式在使用,许多科学家都使用他们自己的规范。开发NetCDF工具和支持NetCDF中的问题之一是产生大量非标准格式的遗留数据。 好消息是UCAR已经初步定义了一些NetCDF规范,比如COARDS规范,它是由海洋-大气合作研究数据服务和CF(气候和预报元数据)发起的。这些规范为NetCDF提供了非常有用的结构和元数据标准。ArcGIS 9.2以及以后的版本中将完全支持这些规范。 netCDF数据模型 一个netCDF数据集包含维、变量和属性三种描述类型,每种类型都会被分配一个名字和一个ID,这些类型共同描述了一个数据集,netCDF库可以同时访问多个数据集,这时就是用ID来识别的。 另外,这三种类型的命名是有规则的,只能由字母组成(再加上'_','.','-'),而且字母是大小写敏感的,即大小写不一样时是不同的,例如,temperature和_temp都是可以的,而Temp和temp是两个不同的东西 netCDF数据集的组成 维(dimensions) 定义方法:维的名字 = 维的大小 例如: 我们要定义经度维,这个经度维含有5个经度,那么可以定义 lon = 5 定义高度维,如含有19个高度值,那么定义 level = 19 另外在一个数据集中,可以且最多可以含有一个无限大小的维,可以把它定义为unlimited。例如时间,我们一时不确定时间具体会有多少,那么我们就把时间定义为一个无限的维(unlimited dimension),如果一个变量用有一个无限的维时,那么这个变量可以无限的增长。 time = unlimited 无限的维也称为记录维(record dimension),因为netCDF系统内部是用这个维作为ID标示记录的。 变量(variable) 变量用来储存数据,使用前必须定义,包括变量的数型、维数、属性等等 数型:就是数据的类型,一般有整数型、实数型等,跟C语言中的变量类型很相似,例如,可以定义: float temperature(time, lat, lon); int lat(lat); 其中温度是浮点型,纬度是整型 维数:这个应该由前面已经定义好的维来定义,当一个变量没有维的定义时,很显然,这个变量只储存一个值,那么这个变量是一个标量,如果有了维的定义,那么这个变量变成类似数组的东西,可以储存多个值。 float temperature(time, lat, lon); 括号里面的就是维 坐标变量(coordinate variables) 就是一系列变量,他们的名字跟维的名字是一样的,维的定义只说明了维的大小,这里可以分别指定维具体取什么值,例如高度维我们定义有4个,那么我们可以分别把这4个高度定为 1000、850、700、500这4个值,但是在内部还是以原始的方式表示,如C语言数组起始的第一个元素的索引是0,而FORTRAN中是1。 使用坐标变量的意义是,我们可以通过一些方法,用这个值来索引得我们的数据,例如netCDF库中提供的一些函数,很可能就是使用这个值来索引,NCL(NCARG Command Language)中也是直接用变量坐标的取值来索引的,例如我们要取1000高度上的数据,直接用1000来索引,而不需要像C语言的数组那样有特定的索引,必需从0开始,当然,这必须通过一些特定的函数来实现,用法如: variables: int level(level); data: level = 1000, 850, 700, 500; 属性(attributes) 变量属性(variable attributes) 一个变量可以拥有很多属性,变量的属性一般是用来说明变量本身的,如对单位、取值范围的说明等,如: int lat(lat); lat:units = "degrees_north"; 这里说明经度的单位是度,向北递增,又如: float rh(time,lat,lon); rh:long_name = "relative humidity"; rh:valid_range = 0.0, 1.0; 这里说明rh的全名是relative humidity,其有效范围是0.0到1.0,注意这里的属性的值可以有多个,即可以是单一的值(标量),也可以是多个值(矢量),但是这时矢量只允许有一维。 全局属性(global attributes) 用来说明整个数据集的一些信息,和变量的attributes一样,但是定义时,前面不加变量名 :attribute_name = list_of_value; 如: :dataset_name = "meteorology dataset"; 数据(Data) netCDF有6种原始的外部数据类型: char 8-bit byte 8-bit integers short 16-bit signed integers int 32-bit signed integers float 32-bit IEEE floating-point real 32-bit IEEE floating-point double 64-bit IEEE floating-point CDL notation CDL表示法是一种表示netCDF文件格式的文本规范,以下是一个范例,非常容易理解 netcdf simple_xy { dimensions: x = 6 ; y = 12 ; variables: int data(x, y) ; data: data = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71 ; } 上面的代码定义了一个符合netcdf格式的结构simple_xy, 这个结构包括三个部分 1、维的定义,以dimensions:关键字开头 dimensions: x = 6 ; y = 12 ; 定义了两个轴(或者说两维),名字分别为x和y,x轴的长度(准确的说是坐标点的个数)为6, y轴的长度为12。 2、变量的定义:以variables:开头 variables: int data(x, y); 定义了一个以x轴和y轴为自变量的函数data,数学公式就是f(x,y)=data; 注意维出现的顺序是有序的,它决定data段中的具体赋值结果. 3、数据的定义,以data:开头 data:data = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71 ; 这个段数据用数学的函数公式f(x,y)=data来看, 就是 x=0,y=0时,data = 0; x=0,y=1时,data = 1; x=5,y=11是,data=71; 要注意的是: 1、赋值顺序: 我们给出的是c格式的cdl文件,因此这里的赋值顺序和c语言中的一致,也就是通常所说的“行式赋值”, 而fortran语言中则是“列式赋值”,因此在fortran格式的cdl文件中,data段的数值顺序和这里正好 行列互换。 2、自变量的默认取值和坐标变量如果只给出维的长度,那么维的值默认从0开始,然后自动加1,到(长度-1)停止,很多情况下我们要自己给出每个点的坐标值,这时就需要用到netcdf里的坐标变量"coordinate varibles":增加一个和只和维相关的一元函数(自变量)并给出它的取值范围。比如下面的cdl文件(摘自netcdf教程中的2.2 The sfc pres temp Example) netcdf sfc_pres_temp { dimensions: latitude = 6 ; //纬度轴 longitude = 12 ; //经度轴 variables: float latitude(latitude) ; //坐标变量,存储具体纬度 latitude:units = "degrees_north" ; float longitude(longitude) ; //坐标变量,存储具体纬度 longitude:units = "degrees_east" ; float pressure(latitude, longitude) ; //某个点(经度和纬度的交点)的大气压值 pressure:units = "hPa" ; //大气压的单位为 float temperature(latitude, longitude) ; //某个点(经度和纬度的交点)的温度值 temperature:units = "celsius" ; //温度的单位为 data: latitude = 25, 30, 35, 40, 45, 50 ; longitude = -125, -120, -115, -110, -105, -100, -95, -90, -85, -80, -75, -70 ; pressure = 900, 906, 912, 918, 924, 930, 936, 942, 948, 954, 960, 966, 901, 907, 913, 919, 925, 931, 937, 943, 949, 955, 961, 967, 902, 908, 914, 920, 926, 932, 938, 944, 950, 956, 962, 968, 903, 909, 915, 921, 927, 933, 939, 945, 951, 957, 963, 969, 904, 910, 916, 922, 928, 934, 940, 946, 952, 958, 964, 970, 905, 911, 917, 923, 929, 935, 941, 947, 953, 959, 965, 971 ; temperature = 9, 10.5, 12, 13.5, 15, 16.5, 18, 19.5, 21, 22.5, 24, 25.5, 9.25, 10.75, 12.25, 13.75, 15.25, 16.75, 18.25, 19.75, 21.25, 22.75, 24.25, 25.75, 9.5, 11, 12.5, 14, 15.5, 17, 18.5, 20, 21.5, 23, 24.5, 26, 9.75, 11.25, 12.75, 14.25, 15.75, 17.25, 18.75, 20.25, 21.75, 23.25, 24.75, 26.25, 10, 11.5, 13, 14.5, 16, 17.5, 19, 20.5, 22, 23.5, 25, 26.5, 10.25, 11.75, 13.25, 14.75, 16.25, 17.75, 19.25, 20.75, 22.25, 23.75, 25.25 对于上面的数据,就是 latitude = 25,longitude = -125时,pressure = 900,temperature = 9; latitude = 25,longitude = -120时,pressure = 906,temperature = 10.5; 以此类推。 参考资料: http://blog.163.com/yuxincastle/blog/static/122125700200961442229151/ http://xiexin163.spaces.live.com/Blog/cns!5C944E34F72DB0C9!167.entry http://www.esrichina-bj.cn/old/market/uc/2005/video7.htm

 

来自http://bbs.esrichina-bj.cn/ESRI/thread-52682-1-1.html

 类似资料: