Java生成NetCDF文件

因为需要再Cesium中实现风场粒子效果,网上找了许多项目,大多是通过加载NC文件来进行渲染的,因此了解NC文件又成了一件重要的事。特此记录用java成果生成可在前端渲染,QGIS中正常渲染的NetCDF文件的相关代码(有没详细整理,给出了初浅的解释)。

这是Geoserver中关于观察NetCDF文件的一份文档地址:

NetCDF — GeoServer 2.26.x User Manual

文中提到的软件可以到github中去下载:Releases · Unidata/netcdf-java (github.com)

从文档中,我们指导,NC文件由维度(Dimension)、变量(Variable)等信息组成(我的应用中主要关注这两个量),同时维度又决定了变量的数组维度

言归正传,直接放代码:

      final int NLon = 500;  // x 轴  设置一个数组里面有几个值final int NLat = 300; // y 轴  设置一个数组里面有几个值
//设置文件输出地址String filename = "D:\\test3D.nc";NetcdfFileWriter dataFile = null;Random random  = new Random();try {//参数1 : 文件格式  参数2:文件名称//先将输出nc文件的基本信息  写入dataFile = NetcdfFileWriter.createNew(NetcdfFileWriter.Version.netcdf3, filename);//创建time depth// Create netCDF dimensions,   创建 nc 文件的维度Dimension timeDim = dataFile.addDimension(null, "time", 1); // 维度X轴 对象  值为:  x = NX;Dimension depthDim = dataFile.addDimension(null, "depth", 1); // 维度Y轴 y = NY;List<Dimension> timeDims = new ArrayList<>();timeDims.add(timeDim);List<Dimension> depthDims = new ArrayList<>();depthDims.add(depthDim);Variable timeVariable = dataFile.addVariable(null, "time", DataType.DOUBLE, timeDims);Attribute timeAttri = new Attribute("units", "hours since 2021-03-23 12:00:00.000 UTC");Attribute timeDescriAttri = new Attribute("description", "Forecast time for ForecastModelRunCollection");timeVariable.addAttribute(timeAttri);timeVariable.addAttribute(timeDescriAttri);Variable depthVariable = dataFile.addVariable(null, "depth", DataType.DOUBLE, depthDims);Attribute depthAttri = new Attribute("units", "m");Attribute depthDescriAttri = new Attribute("description", "Depth");depthVariable.addAttribute(depthAttri);depthVariable.addAttribute(depthDescriAttri);//创建 nc 文件的维度Dimension lonDim = dataFile.addDimension(null, "lon", NLon); // 维度X轴 对象  值为:  x = NX;Dimension latDim = dataFile.addDimension(null, "lat", NLat); // 维度Y轴 y = NY;//写入lon lat数据List<Dimension> lonDims = new ArrayList<>();lonDims.add(lonDim);Variable lonVariable = dataFile.addVariable(null, "lon", DataType.DOUBLE, lonDims);Attribute lonAttri = new Attribute("units", "degrees_east");Attribute lonDescriAttri = new Attribute("description", "Longitude");lonVariable.addAttribute(lonAttri);lonVariable.addAttribute(lonDescriAttri);List<Dimension> latDims = new ArrayList<>();latDims.add(latDim);Variable latVariable = dataFile.addVariable(null, "lat", DataType.DOUBLE, latDims);Attribute latAttri = new Attribute("units", "degrees_north");Attribute latDescriAttri = new Attribute("description", "Latitude");latVariable.addAttribute(latAttri);latVariable.addAttribute(latDescriAttri);//添加 U V变量List<Dimension> uDims = new ArrayList<>();uDims.add(timeDim);uDims.add(depthDim);uDims.add(latDim);uDims.add(lonDim);List<Dimension> vDims = new ArrayList<>();vDims.add(timeDim);vDims.add(depthDim);vDims.add(latDim);vDims.add(lonDim);Variable uVariable = dataFile.addVariable(null, "U", DataType.FLOAT, uDims);Attribute uAttri = new Attribute("units", "m/s");Attribute uDescriAttri = new Attribute("description", "Eastward Water Velocity");uVariable.addAttribute(uAttri);uVariable.addAttribute(uDescriAttri);Variable vVariable = dataFile.addVariable(null, "V", DataType.FLOAT, vDims);Attribute vAttri = new Attribute("units", "m/s");Attribute vDescriAttri = new Attribute("description", "Northward Water Velocity");vVariable.addAttribute(vAttri);vVariable.addAttribute(vDescriAttri);//创建文件 --------维度 变量的申明 一定要在创建文件前完成dataFile.create();//生成time depth变量的信息ArrayDouble.D1 timeDataOut = new ArrayDouble.D1(timeDim.getLength());for(int i = 0;i < timeDim.getLength();i++) {timeDataOut.set(i, 45.0);}dataFile.write(timeVariable, timeDataOut);ArrayDouble.D1 depthDataOut = new ArrayDouble.D1(depthDim.getLength());dataFile.write(depthVariable, depthDataOut);//生成lon lat变量的信息ArrayDouble.D1 lonDataOut = new ArrayDouble.D1(lonDim.getLength());for(int i = 0;i < lonDim.getLength();i++) {lonDataOut.set(i, 123.0+ (i*0.01));}dataFile.write(lonVariable, lonDataOut);ArrayDouble.D1 latDataOut = new ArrayDouble.D1(latDim.getLength());for(int i = 0;i < latDim.getLength();i++) {latDataOut.set(i, 23.0+ (i*0.005));}dataFile.write(latVariable, latDataOut);ArrayFloat.D4 uDataOut = new ArrayFloat.D4(timeDim.getLength(),depthDim.getLength(),latDim.getLength(),lonDim.getLength());ArrayFloat.D4 vDataOut = new ArrayFloat.D4(timeDim.getLength(),depthDim.getLength(),latDim.getLength(),lonDim.getLength());for(int t = 0;t < timeDim.getLength();t++) {for(int d = 0;d < depthDim.getLength();d++) {for(int l = 0;l < latDim.getLength();l++) {double latValue = latDataOut.get(l);for(int i = 0;i < lonDim.getLength();i++) {double lonValue = lonDataOut.get(i);uDataOut.set(t, d, l, i, Float.valueOf(random.nextDouble().toString())  );vDataOut.set(t, d, l, i, Float.valueOf(random.nextDouble().toString()));}else {uDataOut.set(t, d, l, i, Float.NaN);vDataOut.set(t, d, l, i, Float.NaN);}}}}}dataFile.write(uVariable, uDataOut);dataFile.write(vVariable, vDataOut);} catch (Exception e) {e.printStackTrace();}finally {if (null != dataFile)try {dataFile.close();} catch (IOException ioe) {ioe.printStackTrace();}}

初浅理解NC文件,可以看做GIS中的栅格数据,上面的做法其实就是划分了宽、高分别为NLon,NLat的矩形区域,让后对每块栅格进行赋值,所以才会有U、V的变量的值要考虑lon、lat的纬度影响。

使用上文提到的数据集查看工具,进行详细观察,相信你也会逐渐了解NC文件的结构。

差点忘了,我这里用到的maven依赖是:

<dependency><groupId>edu.ucar</groupId><artifactId>netcdf-java</artifactId><version>5.3.3</version>
</dependency>

我jdk用的17,jdk8不知道是否还支持。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/28265.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

16. 第十六章 类和函数

16. 类和函数 现在我们已经知道如何创建新的类型, 下一步是编写接收用户定义的对象作为参数或者将其当作结果用户定义的函数. 本章我会展示函数式编程风格, 以及两个新的程序开发计划.本章的代码示例可以从↓下载. https://github.com/AllenDowney/ThinkPython2/blob/master/c…

java程序在运行过程各个内部结构的作用

一&#xff1a;内部结构 一个进程对应一个jvm实例&#xff0c;一个运行时数据区&#xff0c;又包含多个线程&#xff0c;这些线程共享了方法区和堆&#xff0c;每个线程包含了程序计数器、本地方法栈和虚拟机栈接下来我们通过一个示意图介绍一下这个空间。 如图所示,当一个hell…

内窥镜系统设计简介

内窥镜系统设计简介 1. 源由2. 系统组成2.1 光学系统2.2 机械结构2.3 电子系统2.4 软件系统2.5 安全性和合规性2.6 研发与测试2.7 用户培训与支持 3. 研发过程3.1 光学系统Step 1&#xff1a;镜头设计Step 2&#xff1a;光源Step 3&#xff1a;成像传感器 3.2 机械结构Step 1&a…

11.泛型、trait和生命周期(上)

标题 一、泛型数据的引入二、改写为泛型函数三、结构体/枚举中的泛型定义四、方法定义中的泛型 一、泛型数据的引入 下面是两个函数&#xff0c;分别用来取得整型和符号型vector中的最大值 use std::fs::File;fn get_max_float_value_from_vector(src: &[f64]) -> f64…

代码随想录-Day31

455. 分发饼干 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#xff0c;都有一个胃口值 g[i]&#xff0c;这是能让孩子们满足胃口的饼干的最小尺寸&#xff1b;并且每块饼干 j&#xff0c;都…

Python中的命名空间和作用域:解密变量的可见性和生命周期

在 Python 中&#xff0c;命名空间&#xff08;Namespace&#xff09;和作用域&#xff08;Scope&#xff09;是重要的概念&#xff0c;它们决定了变量和函数的可见性和生命周期。理解命名空间和作用域是编写高效、可维护代码的关键。 基本语法 命名空间 命名空间是一个存储…

新视野大学英语2 词组 6.16

decide between rival options 在互相竞争的选项中做出选择 chinese imperial general 中国帝国将军 on a raid into enemy territory 深入敌方领土突袭 on a raid into&#xff1a;“在进入……的突袭行动中”。 通常指军事行动中快速、秘密地侵入敌人控制的区域&#xff0c…

oracle打补丁

1.备份 su - grid -c "crsctl status res -t" cat /proc/meminfo | grep HugePagesls -lrt /dev/ls -lrt /dev/sd*ls -lrt /dev/asm*cat /etc/udev/rules.d/asm***df -hmountfree -g/etc/security/limits.conf/etc/hosts/etc/selinux/config /etc/pam.d/system-aut…

vs+qt5.0 使用poppler 操作库

Poppler 是一个用来生成 PDF 的C类库&#xff0c;从xpdf 继承而来。vs编译库如下&#xff1a; vs中只需要添加依赖库即可 头文件&#xff1a;

从MySQL到NoSQL:分析传统关系型数据库与NoSQL数据库的协同

引言 数据库是一个系统,用来管理和存储数据的地方。数据在数据库中以一种结构化的方式组织,这样能更容易地查询和处理数据。 关系型数据库是基于关系模型的数据库,它将数据存储在不同的表中,每个表都有各自的独一无二的主键。表与表之间通过共享的数据项相互关联。像MySQ…

windows11 生产力工具配置

一、系统安装 官方windows11.iso镜像文件安装操作系统时&#xff0c;会强制要求联网验证&#xff0c;否则无法继续安装操作系统&#xff0c;跳过联网登录账号的方式为&#xff1a;按下【shiftF10】快捷键&#xff0c;调出cmd命令窗口&#xff0c;输入命令 OOBE\BYPASSNRO 等…

【博客720】时序数据库基石:LSM Tree的辅助优化

时序数据库基石&#xff1a;LSM Tree的辅助优化 场景&#xff1a; LSM Tree其实本质是一种思想&#xff0c;而具体是否需要WAL&#xff0c;内存表用什么有序数据结构来组织&#xff0c;磁盘上的SSTable用什么结构来存放&#xff0c;是否需要布隆过滤器来加快不存在数据的判断等…

Python笔记 - TOML配置文件

TOML&#xff08;Tom’s Obvious, Minimal Language&#xff09;是一种配置文件格式&#xff0c;旨在比JSON、YAML等格式更易读、更人性化。它使用简洁的语法&#xff0c;能清晰地表达复杂的结构&#xff0c;同时保留良好的可读性。本文将介绍TOML的基本语法&#xff0c;提供代…

【UE5|水文章】在UMG上显示帧率

参考视频&#xff1a; https://www.youtube.com/watch?vH_NdvImlI68 蓝图&#xff1a;

数值分析笔记(二)函数插值

函数插值 已知函数 f ( x ) f(x) f(x)在区间[a,b]上n1个互异节点 { x i } i 0 n \{{x_i}\}_{i0}^{n} {xi​}i0n​处的函数值 { y i } i 0 n \{{y_i}\}_{i0}^{n} {yi​}i0n​&#xff0c;若函数集合 Φ \Phi Φ中函数 ϕ ( x ) \phi(x) ϕ(x)满足条件 ϕ ( x i ) y i ( i …

Apollo9.0 PNC源码学习之Routing模块

路由:Routing模块根据请求生成导航信息 输入: 地图数据请求,包括:开始和结束位置输出: 路由导航信息 Routing navigation information0 前言 文件结构: modules/routing/ ├── BUILD ├── common ├── conf ├── core ├── cyberfile.xml ├── dag ├── …

数据结构01 栈及其相关问题讲解【C++实现】

栈是一种线性数据结构&#xff0c;栈的特征是数据的插入和删除只能通过一端来实现&#xff0c;这一端称为“栈顶”&#xff0c;相应的另一端称为“栈底”。 栈及其特点 用一个简单的例子来说&#xff0c;栈就像一个放乒乓球的圆筒&#xff0c;底部是封住的&#xff0c;如果你想…

2024年了,苹果可以通话录音了

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 6月11日凌晨&#xff0c;苹果在WWDC24大会上&#xff0c;密集输出了酝酿多时的AI应用更新。苹果对通话、对话、图…

每日一题44:合作过至少三次的演员和导演

一、每日一题 ---------------------- | Column Name | Type | ---------------------- | actor_id | int | | director_id | int | | timestamp | int | ---------------------- timestamp 是这张表的主键(具有唯一值的列).编写解决方案找出合作过至少三…

力扣 SQL题目

185.部门工资前三高的所有员工 公司的主管们感兴趣的是公司每个部门中谁赚的钱最多。一个部门的 高收入者 是指一个员工的工资在该部门的 不同 工资中 排名前三 。 编写解决方案&#xff0c;找出每个部门中 收入高的员工 。 以 任意顺序 返回结果表。 返回结果格式如下所示。 …