一、NetCDF简介
NetCDF全称为network Common Data Format( “网络通用数据格式”),是一个软件库与机器无关的数据格式,支持创建,访问基于数组的科研数据。分别提供了对Java和C / C++ / Fortran语言。 对程序员来说,它和zip、jpeg、bmp文件格式类似,都是一种文件格式的标准。netcdf文件开始的目的是用于存储气象科学中的数据,现在已经成为许多数据采集软件的生成文件的格式。
从数学上来说,netcdf存储的数据就是一个多自变量的单值函数。用公式来说就是f(x,y,z,…)=value, 函数的自变量x,y,z等在netcdf中叫做维(dimension)或坐标轴(axix),函数值value在netcdf中叫做变量(Variables)。而自变量和函数值在物理学上的一些性质,比如计量单位(量纲)、物理学名称在netcdf中就叫属性(Attributes)。

二、需要用到的netcdf的jar

下载地址:https://www.unidata.ucar.edu/

本文使用版本:netcdfAll-4.6.14.jar

需要java 的jdk 8以上版本

三、读取和打印经纬度变量,了解数据组织结构

    public static void main(String[] args) {

        String filename = "pres_temp_4D.nc";
NetcdfFile dataFile = null;
try {
dataFile = NetcdfFile.open(filename, null);
// Get the latitude and longitude Variables.
Variable latVar = dataFile.findVariable("latitude");
Variable lonVar = dataFile.findVariable("longitude");

System.out.println(NCdumpW.printVariableData(latVar, null));
System.out.println(NCdumpW.printVariableData(lonVar, null)); ArrayFloat.D1 latArray;
ArrayFloat.D1 lonArray; latArray = (ArrayFloat.D1) latVar.read();
lonArray = (ArrayFloat.D1) lonVar.read(); System.out.println(NCdumpW.printArray(latArray, "lat", null));
System.out.println(NCdumpW.printArray(lonArray, "lon", null)); // The file is closed no matter what by putting inside a try/catch block.
} catch (java.io.IOException e) {
e.printStackTrace();
return; } catch (InvalidRangeException e) {
e.printStackTrace();
return; } finally {
if (dataFile != null)
try {
dataFile.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
System.out.println("*** SUCCESS reading example file " + filename); }
NC数据格式:经度:从左到右(正走),纬度:从下到上(正走)
.read():是读取这个变量所有的数据。
四、读取所有格点数据实例
@Override
public Map<String,Object> getNCDataFromFlex(String searchDate,String elementName,String levelType)
{
DecimalFormat decimalFormat=new DecimalFormat(".00");//构造方法的字符格式这里如果小数不足2位,会以0补足
//接口需求:经度:从左到右(正走),纬度:从上到下(负走)
//NC数据格式:经度:从左到右(正走),纬度:从下到上(正走)
String flex_nc_dir=ConfigManager.getInstance().GetProperty("flex_nc_dir");
Map<String, Object> item = new HashMap<String, Object>();
int rows=73;
int cols=73;
item.put("cols", rows);
item.put("rows", cols);
item.put("startLon",113.35373);//sart到end,是小到大
item.put("startLat",37.99601);//sart到end,是大到小
item.put("endLon",115.84625);
item.put("endLat",36);
item.put("stepLon",0.034);//0.034
item.put("stepLat",-0.027);
item.put("missValue",0);
String filePath="";
float [][] uArray = new float[rows][cols];
float [][] vArray = new float[rows][cols]; //NC数据格式:经度:从左到右(正走),纬度:从下到上(正走)
NetcdfFile dataFile = null;
try { String dateStr="";
Date times=DateUtil.strToDate(searchDate,"yyyyMMddHHmmss");
int hour=times.getHours();
if(hour>=6)//早上6点以后就用当天的结果
{
hour=hour+1;
dateStr=DateUtil.dateToStr(times,"yyyyMMddHHmmss").substring(0,8);
}
filePath=flex_nc_dir+dateStr+"/"+dateStr+".nc";
log.info(filePath);
dataFile = NetcdfFile.open(filePath, null); int[] origin = new int[]{hour, 0, 0};//开始位置:时间,经度,纬度
int[] size = new int[]{1, rows, cols};//数据大小:时间,经度,纬度 //输出UV
Variable u_Var = dataFile.findVariable("U10");
Variable v_Var = dataFile.findVariable("V10"); float[] u_Array=(float[]) u_Var.read(origin, size).copyTo1DJavaArray();
float[] v_Array=(float[]) v_Var.read(origin, size).copyTo1DJavaArray(); for(int i = 0 ; i < rows; i=i+1)
{
for(int j = 0; j< cols; j = j+1 )
{
uArray[rows-i-1][j] = Float.parseFloat(decimalFormat.format(u_Array[i *cols +j]));
vArray[i][j] = Float.parseFloat(decimalFormat.format(v_Array[i *cols +j]));
}
} } catch (java.io.IOException e) {
e.printStackTrace();
return null; } catch (InvalidRangeException e) {
e.printStackTrace();
return null; }finally {
if (dataFile != null)
try {
dataFile.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
item.put("uArrays",uArray);
item.put("vArrays",vArray);
return item;
}
read(origin, size):是根据开始位置origin开始读取,然后读取size数据量的数据出来。
.copyTo1DJavaArray():是将多维变量转换成一维数组。

五、根据点位所在的经纬度,读取该位置的变量值

@Override
public Map<String,Object> getNCFactorFromFlex(String searchDate,float lon,float lat)
{
DecimalFormat decimalFormat=new DecimalFormat(".00");//构造方法的字符格式这里如果小数不足2位,会以0补足
//接口需求:经度:从左到右(正走),纬度:从上到下(负走)
//NC数据格式:经度:从左到右(正走),纬度:从下到上(正走)
String flex_nc_dir=ConfigManager.getInstance().GetProperty("flex_nc_dir");
int rows=73;
int cols=73;
String filePath=""; float u_value=0;
float v_value=0;
float p_value=0;
float rh_value=0; //NC数据格式:经度:从左到右(正走),纬度:从下到上(正走)
NetcdfFile dataFile = null;
try { String dateStr="";
Date times=DateUtil.strToDate(searchDate,"yyyyMMddHHmmss");
int hour=times.getHours();
if(hour>=6)//早上6点以后就用times当天的结果
{
hour=hour+1;
dateStr=DateUtil.dateToStr(times,"yyyyMMddHHmmss").substring(0,8);
}
else//上6点前就用times前一天的结果
{
hour=hour+24+1;
dateStr=DateUtil.dateToStr(DateUtil.dateAdd(times,"d",-1),"yyyyMMddHHmmss").substring(0,8);
}
filePath=flex_nc_dir+dateStr+"/"+dateStr+".nc";
log.info("getNCFactorFromFlex"+filePath); dataFile = NetcdfFile.open(filePath, null); //00开始,读取第一个网格,用于计算经度序号,纬度序号
int[] origin0 = new int[]{0, 0, 0};//开始位置:时间序号,经度序号,纬度序号
int[] size0 = new int[]{1, 73, 73};//数据大小:时间,经度,纬度 Variable x_Var = dataFile.findVariable("XLONG");
Variable y_Var = dataFile.findVariable("XLAT");
float[] x_Array=(float[]) x_Var.read(origin0, size0).copyTo1DJavaArray();
float[] y_Array=(float[]) y_Var.read(origin0, size0).copyTo1DJavaArray(); int x_xh=getLonXHfromNetcdf(x_Array,lon);
int y_xh=getLatXHfromNetcdf(y_Array,lat); int[] origin = new int[]{hour, x_xh, y_xh};//开始位置:时间序号,经度序号,纬度序号
int[] size = new int[]{1, 1, 1};//数据大小:时间,经度,纬度 Variable u_Var = dataFile.findVariable("U10");
Variable v_Var = dataFile.findVariable("V10");
Variable p_Var = dataFile.findVariable("PSFC");
Variable rh_Var = dataFile.findVariable("rh2"); float[] u_Array=(float[]) u_Var.read(origin, size).copyTo1DJavaArray();
float[] v_Array=(float[]) v_Var.read(origin, size).copyTo1DJavaArray();
float[] p_Array=(float[]) p_Var.read(origin, size).copyTo1DJavaArray();
float[] rh_Array=(float[]) rh_Var.read(origin, size).copyTo1DJavaArray(); u_value=u_Array[0];
v_value=v_Array[0];
p_value=p_Array[0];
rh_value=rh_Array[0]; } catch (java.io.IOException e) {
e.printStackTrace();
} catch (InvalidRangeException e) {
e.printStackTrace();
}finally {
if (dataFile != null)
try {
dataFile.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
Map<String, Object> item=ClearCalUtil.getWindSpeed(u_value,v_value);
item.put("u_value",Numberdf.format(u_value));
item.put("v_value",Numberdf.format(v_value));
item.put("p_value",Math.round(p_value/100));
item.put("rh_value",Math.round(rh_value));
return item;
}
public int getLonXHfromNetcdf(float[] x_arr,float lon)
{
//纬度数据,列:从前到后,变大;行:从前到后,不变,所以只需要遍历第1行的所有列即可
int lon_xh=0;
int rows=73;
int cols=73;
for(int i = 0; i< 1; i = i+1 )
{
for(int j = 0; j< cols; j = j+1 )
{
float temp=x_arr[i *cols+j];
if(temp>lon)
{
lon_xh=j;
return lon_xh;
}
}
} return lon_xh;
}
public int getLatXHfromNetcdf(float[] y_arr,float lat)
{
//纬度数据,列:从前到后,不变;行:从前到后,变大,所以只需要遍历第1列的所有行即可
int lat_xh=0;
int rows=73;
int cols=73;
for(int i = 0; i< rows; i = i+1 )
{
for(int j = 0; j< 1; j = j+1 )
{
float temp=y_arr[i *cols+j];
if(temp>lat)
{
lat_xh=i;
return lat_xh;
}
}
} return lat_xh;
}

其他读取方法

   // read 3D array for that index
ArrayFloat.D3 presArray, tempArray; presArray = (ArrayFloat.D3) (presVar.read(origin, shape).reduce());
tempArray = (ArrayFloat.D3) (tempVar.read(origin, shape).reduce()); // now checking the value
int count = 0;
for (int lvl = 0; lvl < NLVL; lvl++)
for (int lat = 0; lat < NLAT; lat++)
for (int lon = 0; lon < NLON; lon++) {
if ((presArray.get(lvl, lat, lon) != SAMPLE_PRESSURE + count) ||
(tempArray.get(lvl, lat, lon) != SAMPLE_TEMP + count))
System.err.println("ERROR incorrect value in variable pressure or temperature");
count++;
}
}

java 读取气象专业格式NetCDF文件的更多相关文章

  1. 【转】Java读取matlab的.mat数据文件

    参考:Java读取mat文件 下载链接:ujmp  jmatio 下载完两个.jar文件之后,如何引用到java项目当中?项目名称->右键->Property->Java Build ...

  2. 解决:java 读取 resources 下面的 json 文件

    前言:java 读取 工程下的配置文件,文件类型为 json(*.json),记录一下始终读取不到 json 文件的坑.maven项目 直接上工具类代码 package com.yule.compon ...

  3. java读取resource/通过文件名获取文件类型

    java读取resource java读取resource目录下文件的方法: 借助Guava库的Resource类 Resources.getResource("test.txt" ...

  4. java读取目录下所有csv文件数据,存入三维数组并返回

    package dwzx.com.get; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; ...

  5. java 读取固定目录下的文件(和上篇差点儿相同)

    package gao.org; import java.io.FileNotFoundException; import java.io.IOException; import java.io.Fi ...

  6. java读取jar包中的文件

    随手写了一个java小工具,maven打包成功后,发现工具总是读不到打在jar包中的文件信息,要读取的文件位于 /src/main/resources 目录下,打包成功后,文件就在jar包中根目录下, ...

  7. java读取package中的properties文件java.util.MissingResourceException

    文件结构: /build/classes/d914/Hello.class /build/classes/d914/mess.properties /build/classes/d914/mess_z ...

  8. Java 读取目录下的所有文件

    package util; import java.io.File; import java.util.ArrayList; import java.util.List; import org.apa ...

  9. Java 读取某个目录下所有文件、文件夹

    /** * @Author: * @Description:获取某个目录下所有直接下级文件,不包括目录下的子目录的下的文件,所以不用递归获取 * @Date: */ public static Lis ...

  10. Java读取CSV和XML文件方法

    游戏开发中,读取策划给的配置表是必不可少的,我在之前公司,策划给的是xml表来读取,现在公司策划给的是CSV表来读取,其实大同小异,也并不是什么难点,我就简单分享下Java如何读取XML文件和CSV文 ...

随机推荐

  1. 浅谈ET框架--ECS设计核心(一)

    ET框架的ECS设计核心可以总结为一句话,那就是: 继承转组件,多态转分发 OOP设计里的继承更换为组件Component模式,多态转成分发模式. 框架代码里头的案例: 数值组件挂载Entity上. ...

  2. #特征方程,dp,快速幂#洛谷 4451 [国家集训队]整数的lqp拆分

    题目 分析 设\(dp[n]\)表示答案,因为\(dp[n]=\sum\prod_{i=1}^mF_{a_i}\) \(dp[n]=\sum_{i=1}^{n-1}dp[i]*F_{n-i-1}\) ...

  3. Java中的类型推断和lambda表达式

    目录 简介 类型的显示使用 Stream中的类型推断 类型推断中变量名字的重要性 类型推断对性能的影响 类型推断的限制 总结 简介 java是强类型的编程语言,每个java中使用到的变量都需要定义它的 ...

  4. 重磅官宣 | 第二届OpenHarmony技术峰会,邀您共启智联未来

      "下一个技术未来在哪里?" 11月4日  技术大咖齐聚北京为你解答 一场主论坛+八大开源领域分论坛 探究终端操作系统十大技术挑战方向 与全球开源操作系统技术领袖.实践专家.一线 ...

  5. 从模型到部署,教你如何用Python构建机器学习API服务

    本文分享自华为云社区<Python构建机器学习API服务从模型到部署的完整指南>,作者: 柠檬味拥抱. 在当今数据驱动的世界中,机器学习模型在解决各种问题中扮演着重要角色.然而,将这些模型 ...

  6. Django Admin:自动选择当前用户

    --转载自:林肯李 该文章写的很好,特转载留待后期备用 背景 在开发 CMS 时,经常需要标记谁创建了记录.Django 为我们提供了一个很好的管理界面.但是当我们只使用默认值时,用户需要自己选择他们 ...

  7. openGauss单机部署

    openGauss 单机部署 一.安装环境 操作系统:虚拟机 VMware.CentOS7.9 环境设置: (1)虚拟机内存 3G.磁盘 100G (2)系统版本修改 一开始使用了 centos8,无 ...

  8. 容器开发运维人员的 Linux 操作机配置优化建议

    "工欲善其事必先利其器", 作为一个PAAS平台架构师, 容器相关技术(docker, k8s等)是必不可少的. 本文简单介绍下我自己的Linux操作机配置. 提升工作效率, 提高 ...

  9. HarmonyOS跨进程通信—IPC与RPC通信开发指导

      一.IPC与RPC通信概述 基本概念 IPC(Inter-Process Communication)与RPC(Remote Procedure Call)用于实现跨进程通信,不同的是前者使用Bi ...

  10. 局部区块多个报表 TAB 页切换及局部区块的参数查询

    在企业的业务系统中,如何从纷繁复杂的数据中抽丝剥茧看到关键数据信息呢?一个重要的途径就是将企业和各部门运营中关键的 KPI 集中在一起显示,同时尽量省去在企业的各个业务系统中分别查找数据. 下面是我近 ...