NetCDF全称为network Common Data Format,中文译法为“网络通用数据格式”,对程序员来说,它和zip、jpeg、bmp文件格式类似,都是一种文件格式的标准。netcdf文件开始的目的是用于存储气象科学中的数据,现在已经成为许多数据采集软件的生成文件的格式。

从数学上来说,netcdf存储的数据就是一个多自变量的单值函数。用公式来说就是f(x,y,z,…)=value, 函数的自变量x,y,z等在netcdf中叫做维(dimension) 或坐标轴(axix),函数值value在netcdf中叫做变量(Variables).而自变量和函数值在物理学上的一些性质,比如计量单位(量纲)、物理学名称等等

1、变量(Variables)

变量对应着真实的物理数据。比如我们家里的电表,每个时刻显示的读数表示用户的到该时刻的耗电量。这个读数值就可以用netcdf里的变量来表示。它是一个以时间为自变量(或者说自变量个数为一维)的单值函数。再比如在气象学中要作出一个气压图,就是“东经xx度,北纬yy度的点的大气压值为多少帕”,这是一个二维单值函数,两维分别是经度和纬度。函数值为大气压。

从上面的例子可以看出,netcdf中的变量就是一个N维数组,数组的维数就是实际问题中的自变量个数,数组的值就是观测得到的物理值。变量(数组值)在netcdf中的存储类型有六种,ascii字符(char) ,字节(byte), 短整型(short), 整型(int), 浮点(float), 双精度(double). 显然这些类型和c中的类型一致,搞C的朋友应该很快就能明白。

2、维(dimension)

一个维对应着函数中的某个自变量,或者说函数图象中的一个坐标轴,在线性代数中就是一个N维向量的一个分量(这也是维这个名称的由来)。在netcdf中,一个维具有一个名字和范围(或者说长度,也就是数学上所说的定义域,可以是离散的点集合或者连续的区间)。在netcdf中,维的长度基本都是有限的,最多只能有一个具有无限长度的维,例如:
dimensions:
time = 1;
isobaric = 1;
lat = 281;
lon = 361;

3、属性(Attribute)

属性对变量值和维的具体物理含义的注释或者说解释。因为变量和维在netcdf中都只是无量纲的数字,要想让人们明白这些数字的具体含义,就得靠属性这个对象了。 在netcdf中,属性由一个属性名和一个属性值(一般为字符串)组成。例如:

***
variables:
float longitude(lon=361);:units = "degrees_east";
float latitude(lat=281);:units = "degrees_north";***

float是变量类型,longitude时一个定义好的Variables变量,即经度,:units=“degrees_east”;组成一个属性,units为属性名,degrees_east为属性值。

package com.DateRW;import java.io.IOException;
import java.util.ArrayList;
import java.util.List;import ucar.ma2.ArrayFloat;
import ucar.ma2.ArrayInt;
import ucar.ma2.DataType;
import ucar.ma2.Index;
import ucar.ma2.InvalidRangeException;
import ucar.nc2.Attribute;
import ucar.nc2.Dimension;
import ucar.nc2.NetcdfFile;
import ucar.nc2.NetcdfFileWriter;
import ucar.nc2.Variable;
import ucar.nc2.NetcdfFileWriter.Version;/*** 将grib数据用NC存储* @author EncodingKing* @date 2020-4-8**/
public class grib_nc {public static void main(String[] args) {//读取grib文件路径String gribPath="E:Grib\\C4U\\W_NAFP_C_ECMF_20200307200247_P_C4U03071200032212001";//存储NC文件路径String NcPath="E:Grib\\C4U\\gripNc2";try {NetcdfFile openGrib=NetcdfFile.open(gribPath);//获取time变量    Variable time=openGrib.findVariable("time");double[] dateTime=(double[]) time.read().copyTo1DJavaArray();//获取经度Variable lon=openGrib.findVariable("lon");float[] dateLon=(float[]) lon.read().copyTo1DJavaArray();  //获取纬度Variable lat=openGrib.findVariable("lat");float[] dateLat=(float[]) lat.read().copyTo1DJavaArray();//获取有效波高变量Variable Significant_wave_heigh=openGrib.findVariable("Significant_wave_height_of_at_least_6_m_msl_120_Hour_2");//获取时间经纬度数组的长度int dateTimeL=dateTime.length;int dateLonL=dateLon.length;int dateLatL=dateLat.length;//将有效波高变量放到三维数组中float[][][] threeArr=(float[][][]) Significant_wave_heigh.read().copyToNDJavaArray();System.out.println("arrD.length="+threeArr.length+" arrD[0].length="+threeArr[0].length + " arrD[0][0].length="+threeArr[0][0].length);//拼接NC文件路径NetcdfFileWriter fileWriter = NetcdfFileWriter.createNew(Version.netcdf3, NcPath+".nc");//创建一维自变量Dimension timeDim=fileWriter.addDimension(null, "time", dateTimeL);Dimension latDim=fileWriter.addDimension(null, "lat", dateLatL);Dimension lonDim=fileWriter.addDimension(null, "lon", dateLonL);//将一维合成二维listArrayList<Dimension> dim=new ArrayList<>();//与前边定义的一维自变量顺序保持一致dim.add(timeDim);dim.add(latDim);dim.add(lonDim);// 创建名称为lon的变量,类型为folat,对应的维度为lon,对应Dimension里面定义的名称为"lon"Variable vx = fileWriter.addVariable(null, "lon", DataType.FLOAT,"lon");List<Attribute> attributesLon = lon.getAttributes();for (int i = 0; i < attributesLon.size(); i++) {String[] strResut = attributesLon.get(i).toString().split("=");                fileWriter.addVariableAttribute(vx, new Attribute(strResut[0].trim(),strResut[1].replace("\"", "").trim()));}// 创建名称为lat的变量,类型为folat,对应Dimension里面定义的名称为"lat"Variable vy = fileWriter.addVariable(null, "lat", DataType.FLOAT,"lat");List<Attribute> attributesLat = lat.getAttributes();for (int i = 0; i < attributesLat.size(); i++) {String[] strResut = attributesLat.get(i).toString().split("=");                fileWriter.addVariableAttribute(vy, new Attribute(strResut[0].trim(),strResut[1].replace("\"", "").trim()));}// 创建名称为time的变量,类型为double,对应Dimension里面定义的名称为"time"Variable vt = fileWriter.addVariable(null, "time", DataType.DOUBLE,"time");List<Attribute> attributesTime = time.getAttributes();for (int i = 0; i < attributesTime.size(); i++) {String[] strResut = attributesTime.get(i).toString().split("=");              fileWriter.addVariableAttribute(vt, new Attribute(strResut[0].trim(),strResut[1].replace("\"", "").trim()));}// 创建变量名称为value的变量,对应的维度为dims,Variable v = fileWriter.addVariable(null, "value", DataType.FLOAT,dim);List<Attribute> attributesD = Significant_wave_heigh.getAttributes();for (int i = 0; i < attributesD.size(); i++) {String[] strResut = attributesD.get(i).toString().split("=");              fileWriter.addVariableAttribute(v, new Attribute(strResut[0].trim(),strResut[1].replace("\"", "").trim()));}List<Attribute> globalAttributes = openGrib.getGlobalAttributes();for (int i = 0; i < globalAttributes.size(); i++) {String[] strResut = globalAttributes.get(i).toString().split("=");               fileWriter.addGroupAttribute(null, new Attribute(strResut[0].trim(),strResut[1].replace("\"", "").trim()));}//创建文件fileWriter.create();//设置一维变量ArrayInt timeValues = new ArrayInt.D1(dateTimeL);ArrayFloat latValues = new ArrayFloat.D1(dateLatL);ArrayFloat lonValues = new ArrayFloat.D1(dateLonL);//设置三维变量ArrayFloat values=new ArrayFloat.D3(dateTimeL, dateLatL, dateLonL);//设置索引Index index = values.getIndex();for(int a=0;a<dateTimeL;a++){//给time变量赋值,此处的值是从dateTime[]数组中取出的。timeValues.setDouble(a, dateTime[a]);for(int b=0;b<dateLatL;b++){//给lat赋值latValues.setFloat(b, dateLat[b]);for(int c=0;c<dateLonL;c++){//给lon赋值lonValues.setFloat(c, dateLon[c]);//将threeArr[][][]三维数组中的值,对应index.set(a, b, c)坐标放入;values.setDouble(index.set(a, b, c), threeArr[a][b][c]);}}}fileWriter.write(vt, timeValues);fileWriter.write(vy, latValues);fileWriter.write(vx, lonValues);fileWriter.write(v, values);fileWriter.close();System.out.println("文件已存入" + NcPath);} catch (InvalidRangeException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}
}

转成NC后的结果:

netcdf file:/E:/Grib/C4U/gripNc2.nc {dimensions:time = 1;lat = 361;lon = 720;variables:float lat(lat=361);:units = "degrees_north";float lon(lon=720);:units = "degrees_east";int time(time=1);:units = "Hour since 2020-03-07T12:00:00Z";:standard_name = "time";:long_name = "GRIB forecast or observation time";:calendar = "proleptic_gregorian";:bounds = "time_bounds";float value(time=1, lat=361, lon=720);:long_name = "Significant wave height of at least 6 m (120_Hour) @ Mean sea level";:units = "%";:description = "Cloud water";:missing_value = "NaNf";:grid_mapping = "LatLon_Projection";:coordinates = "reftime time lat lon";:Grib_Statistical_Interval_Type = "2";:Grib_Variable_Id = "VAR_98-0-131-76_L102_I120_Hour_S2";:Grib1_Center = "98";:Grib1_Subcenter = "0";:Grib1_TableVersion = "131";:Grib1_Parameter = "76";:Grib1_Parameter_Name = "swhg6";:Grib1_Level_Type = "102";:Grib1_Level_Desc = "Mean sea level";:Grib1_Interval_Type = "2";:Grib1_Interval_Name = "product valid, interval";// global attributes::Originating_or_generating_Center = "European Centre for Medium Range Weather Forecasts (ECMWF) (RSMC)";:Originating_or_generating_Subcenter = "0";:GRIB_table_version = "0,131";:file_format = "GRIB-1";:Conventions = "CF-1.6";:history = "Read using CDM IOSP GribCollection v3";:featureType = "GRID";
}

读取grib/NC数据所需的netcdfall-4.6.11.jar,下方留言,给您及时转载。各位大佬感觉不错的记得点赞哦。

Grib数据转NC数据相关推荐

  1. 写入grib2+java,Grib数据转换成NC数据

    NetCDF全称为network Common Data Format,中文译法为"网络通用数据格式",对程序员来说,它和zip.jpeg.bmp文件格式类似,都是一种文件格式的标 ...

  2. linux下下载fnl数据,python处理FNL数据的grib文件和nc文件(纬度存储的问题)

    python处理FNL数据的grib文件和nc文件(纬度存储的问题) python处理FNL数据的grib文件和nc文件(纬度存储的问题) 在使用python处理FNL数据时,2007年及之前的数据存 ...

  3. 输出nc数据_气象数据处理的火箭加速器—CDO

    happy科研 关注 Hi-新朋友,记得点蓝字关注我们哟 科研到头秃(7) 学渣 今天碰到了一个科研难题,想想都头大 学霸 学渣 模式运行得到了360个逐月输出的文件,NCL处理起来慢爆了,想哭 学霸 ...

  4. python处理nc文件并输出_利用python如何处理nc数据详解

    前言 这两天帮一个朋友处理了些 nc 数据,本以为很简单的事情,没想到里面涉及到了很多的细节和坑,无论是"知难行易"还是"知易行难"都不能充分的说明问题,还是& ...

  5. 合并多个nc数据_气象数据处理的火箭加速器—CDO

    happy科研 关注 Hi-新朋友,记得点蓝字关注我们哟 科研到头秃(7) 学渣 今天碰到了一个科研难题,想想都头大 学霸 学渣 模式运行得到了360个逐月输出的文件,NCL处理起来慢爆了,想哭 学霸 ...

  6. 使用 python 处理 nc 数据

    前言 这两天帮一个朋友处理了些 nc 数据,本以为很简单的事情,没想到里面涉及到了很多的细节和坑,无论是"知难行易"还是"知易行难"都不能充分的说明问题,还是& ...

  7. 输出nc数据_NetCDF(NC)数据的使用、转换和分析

    最近项目中需要处理和分析NC数据,所以我查了一下,百度百科的解释是:NetCDF(network Common Data Form)网络通用数据格式是由美国大学大气研究协会(University Co ...

  8. 保姆级教程:python读取并绘制nc数据

    读取nc数据相关信息 #导入库 import netCDF4 from netCDF4 import Dataset#读取数据文件 nc_file=Dataset("/media/hsy/H ...

  9. python能处理nc文件吗_利用python如何处理nc数据详解

    前言 这两天帮一个朋友处理了些 nc 数据,本以为很简单的事情,没想到里面涉及到了很多的细节和坑,无论是"知难行易"还是"知易行难"都不能充分的说明问题,还是& ...

最新文章

  1. Linux课程设计八音盒,单片机课程设计——八音盒精要.doc
  2. 黄聪:解决Jquery在GET方式传递参数时gb2312中文编码乱码
  3. Python 文件操作二
  4. 邯郸学院计算机专业是本科还是专科,邯郸学院是大学吗 是本科还是专科
  5. 随机生成一个质数的python代码_使用质数生成随机密码
  6. 畅通工程续 最短路
  7. Codeforces Round #727 (Div. 2) 题解
  8. php mqtt qos,Mqtt Qos 深度解读
  9. 单片机测量代码运行时间方法-STM32
  10. Android学习系列--App调试的几个命令实践
  11. mysql 指定ip段 掩码_IP分配及网段划分
  12. JCR分区与中科院分区
  13. GPS开发、定位修改
  14. java 中文url转码_对 url 中含有的中文进行转码操作
  15. 虚拟机的安装及使用介绍
  16. python识别文字并且提示_Python识别文字,实现看图说话|CSDN博文精选
  17. 组台式计算机配置清单整套,组装台式电脑配置清单有哪些 台式电脑什么配置好...
  18. 倒酒(拓展欧几里得)
  19. java 异常之Cause: org.apache.ibatis.executor.ExecutorException: Executor was closed
  20. html怎样写出x的平方,x的平方怎么打出来

热门文章

  1. maven是干嘛的?
  2. Java很傻,但是IDE很聪明,Intellij IDEA 是一款好产品
  3. 基于空间金字塔网络的光流估计
  4. Janus的STUN原理与抓包分析
  5. 刘韧:和人物共同创作人物故事
  6. OpenWrt 系列教程汇总
  7. cad把图形切成两部分_CAD入门教程,最常用快捷键
  8. 个人数字作品合作协议
  9. 汉明码的原理、生成和检验
  10. Delphi和Word编程集锦