气象NC扇形经纬网格转换成前端leaflet-vector-scalar.js要求的等经纬网格
背景:最近从气象局拿到文件格式为NC的气象文件(包括温度、湿度、风、气压、雨量等),需要读取其中的温度数据并在前端展示。用专业软件打开一看,图是扇形的,经纬度间隔也不相等,如下图:

问题:需要读文件格式为NC的气象文件中的温度数据,并转换为leaflet-vector-scalar.js要求的等经纬网格JSON数据。
解决:通过JAVA调用netcdf包读取NC文件,将NC扇形经纬网格转换成等经纬网格,转换思路如下:
将扇形经纬网格1、2、3、4(红色格)数值相加求平均值,赋值给等经纬网格a(黑色格)实现JAVA代码如下:

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import ucar.ma2.ArrayFloat;
import ucar.ma2.DataType;
import ucar.nc2.*;public class CreateNetCDF_2D_TEMP {public final static float MISSING_VALUE = -9.96921E36f;public final static String TMP_DIR = "D:/";public static void main(String[] args) throws Exception {//last 'aa' is 'AM' or 'PM'. 'HH' is 24 hour system. if you change it to 'hh', it means 12 hour systemSimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss aa");NetcdfFile ncfile = null;NetcdfFileWriter writer = null;//自定义等间距网格数int xGridsNum = 350;int yGridsNum = 300;try {ncfile = NetcdfFile.open("d:/temp.nc");// Get the latitude and longitude Variables.Variable latVarO = ncfile.findVariable("NLAT");Variable lonVarO = ncfile.findVariable("ELON");// Get the temperature Variables.Variable tmpVariable = ncfile.findVariable("TMP");ArrayFloat.D2 latArray;ArrayFloat.D2 lonArray;ArrayFloat.D2 tmpArray;latArray = (ArrayFloat.D2) latVarO.read();lonArray = (ArrayFloat.D2) lonVarO.read();tmpArray = (ArrayFloat.D2) tmpVariable.read();//Calculate latitude and longitude rangefloat minLat = 99999f, maxLat = 0f;float minLon = 99999f, maxLon = 0f;int latGridsNumO = latVarO.getDimension(0).getLength();int lonGridsNumO = latVarO.getDimension(1).getLength();//使用原始NC数据中网格数//xGridsNum = latGridsNumO;//yGridsNum = lonGridsNumO;//Calculate temperature rangefloat minTmp = 99999f, maxTmp = 0f;for(int j=0;j<lonGridsNumO;j++) {for(int i=0; i<latGridsNumO; i++) {float fLat = latArray.get(i,j);float fLon = lonArray.get(i,j);float fTemp = tmpArray.get(i,j);//latData.set(i,j, f);//lonData.set(i,j, f);if(maxLat<fLat) maxLat = fLat;if(minLat>fLat) minLat = fLat;if(maxLon<fLon) maxLon = fLon;if(minLon>fLon) minLon = fLon;if(maxTmp<fTemp) maxTmp = fTemp;if(minTmp>fTemp) minTmp = fTemp;}}System.out.println("lo1:" + minLon);System.out.println("lo2:" + maxLon);System.out.println("la1:" + maxLat);System.out.println("la2:" + minLat);System.out.println("nx:" + xGridsNum);System.out.println("ny:" + yGridsNum);System.out.println("minTEMP:" + minTmp);System.out.println("maxTEMP:" + maxTmp);//定义新的NC文件String varname = "temp0";writer = NetcdfFileWriter.createNew(NetcdfFileWriter.Version.netcdf3, TMP_DIR+varname+".nc");//经度纬度维度定义Dimension latDimension = writer.addDimension(null, "lat", yGridsNum);Dimension lonDimension = writer.addDimension(null, "lon", xGridsNum);//纬度变量属性设置Variable latVar = writer.addVariable(null, "lat", DataType.FLOAT, Arrays.asList(lonDimension,latDimension));latVar.addAttribute(new Attribute("units", "Degrees_north"));latVar.addAttribute(new Attribute("description", "Latitude"));latVar.addAttribute(new Attribute("long_name", "Latitude"));latVar.addAttribute(new Attribute("standard_name", "latitude"));latVar.addAttribute(new Attribute("axis", "Y"));latVar.addAttribute(new Attribute("coordinate_defines", "center"));latVar.addAttribute(new Attribute("actual_range",Arrays.asList(minLat, maxLat)));//经度变量属性设置Variable lonVar = writer.addVariable(null, "lon", DataType.FLOAT, Arrays.asList(lonDimension,latDimension));lonVar.addAttribute(new Attribute("units", "Degrees_east"));lonVar.addAttribute(new Attribute("description", "Longitude"));lonVar.addAttribute(new Attribute("long_name", "Longitude"));lonVar.addAttribute(new Attribute("standard_name", "longitude"));lonVar.addAttribute(new Attribute("axis", "X"));lonVar.addAttribute(new Attribute("coordinate_defines", "center"));lonVar.addAttribute(new Attribute("actual_range",Arrays.asList(minLon, maxLon)));//温度变量属性设置Variable tempVar = writer.addVariable(null, varname, DataType.FLOAT, Arrays.asList(lonDimension,latDimension));tempVar.addAttribute(new Attribute("units", "degK"));tempVar.addAttribute(new Attribute("description", "Temperature temp"));tempVar.addAttribute(new Attribute("missing_value", MISSING_VALUE));tempVar.addAttribute(new Attribute("dataset", "NOAA/NCEP GHCN CAMS"));tempVar.addAttribute(new Attribute("var_desc", "Air Temperature"));tempVar.addAttribute(new Attribute("valid_range", Arrays.asList(150.0f,400.0f)));//add global attributeswriter.addGroupAttribute(null, new Attribute("SOUTH-NORTH_GRID_DIMENSION", latDimension.getLength()));writer.addGroupAttribute(null, new Attribute("WEST-EAST_GRID_DIMENSION", lonDimension.getLength()));writer.addGroupAttribute(null, new Attribute("TITLE", "NOAA/NCEP GHCN CAMS Monthly Temperature"));writer.addGroupAttribute(null, new Attribute("Conventions", "CF-1.0"));//定义新NC文件中经度、纬度、温度变量数组ArrayFloat.D2 latData = new ArrayFloat.D2(lonDimension.getLength(), latDimension.getLength());ArrayFloat.D2 lonData = new ArrayFloat.D2(lonDimension.getLength(), latDimension.getLength());ArrayFloat.D2 tempData = new ArrayFloat.D2(lonDimension.getLength(), latDimension.getLength());//纬度网格间距float latLen = Math.abs(maxLat-minLat)/latDimension.getLength();//经度网格间距float lonLen = Math.abs(maxLon-minLon)/lonDimension.getLength();System.out.println("dy:" + latLen);System.out.println("dx:" + lonLen);//创建一个线程池ExecutorService pool = Executors.newCachedThreadPool();for(int j=0; j<latDimension.getLength(); j++) {for(int i=0; i<lonDimension.getLength(); i++) {float tempLat = minLat + j*latLen;float tempLon = minLon + i*lonLen;latData.set(i,j, tempLat);lonData.set(i,j, tempLon);//Date date0 = new Date();//System.out.println("线程" + i + "," + j + "开启时间" + sdf.format(date0));//计算等经纬网格中J,I网格的值Callable c = new MyCallable(latGridsNumO,lonGridsNumO,latArray,lonArray,tmpArray,tempLat,tempLon,latLen,lonLen);//执行任务并获取 Future 对象Future future = pool.submit(c);float f = Float.parseFloat(future.get().toString());tempData.set(i,j, f);}}tempVar.addAttribute(new Attribute("actual_range", Arrays.asList(minTmp, maxTmp)));// 关闭线程池pool.shutdown();//将数组中的数据组装成字符串。数据之间','间隔String TEMPData = "";for(int j=latDimension.getLength()-1;j>-1;j--){for(int i=0;i<lonDimension.getLength();i++) {if(j==0&&i==lonDimension.getLength()-1){TEMPData += tempData.get(i,j) + "";}else{TEMPData += tempData.get(i,j) + ",";}}}//将温度数据写入txtFile file = new File("d:\\outTmp.txt"); //存放数组数据的文件java.io.FileWriter out = new  java.io.FileWriter(file); //文件写入流out.write(TEMPData);out.close();//创建新的NC文件,并写入值writer.create();writer.write(latVar, latData);writer.write(lonVar, lonData);writer.write(tempVar, tempData);//打印温度值总数量System.out.println("Temperature value number:" + tempData.getSize());//System.out.println(tempData.get(tempData.getSize()-1).toString());writer.close();//前端需要返回的参数
//          float lo1 = minLon;
//          float lo2 = maxLon;
//          float la1 = maxLat;
//          float la2 = minLat;
//          int nx = xGridsNum;
//          int ny = yGridsNum;
//          float dy = latLen;
//          float dx = lonLen;
//          String data = TEMPData;
//          float minTEMP = minTmp;
//          float maxTEMP = maxTmp;} finally {ncfile.close();}}}class MyCallable implements Callable<Object> {//参数定义int latGridsNumO;int lonGridsNumO;ArrayFloat.D2 latArray;ArrayFloat.D2 lonArray;ArrayFloat.D2 tmpArray;float tempLat;float tempLon;float latLen;float lonLen;MyCallable(int latGridsNumO,int lonGridsNumO,ArrayFloat.D2 latArray,ArrayFloat.D2 lonArray,ArrayFloat.D2 tmpArray,float tempLat,float tempLon,float latLen,float lonLen) {this.latGridsNumO = latGridsNumO;this.lonGridsNumO = lonGridsNumO;this.latArray = latArray;this.lonArray = lonArray;this.tmpArray = tmpArray;this.tempLat = tempLat;this.tempLon = tempLon;this.latLen = latLen;this.lonLen = lonLen;}public Object call() throws Exception {float tempTmps = 0f;int tempNum = 0;for(int jLat=0; jLat<this.lonGridsNumO; jLat++) {for (int iLon = 0; iLon < this.latGridsNumO; iLon++) {if(this.latArray.get(iLon,jLat)>=(tempLat-latLen) &&this.latArray.get(iLon,jLat)<=(tempLat+latLen) &&this.lonArray.get(iLon,jLat)>=(tempLon-lonLen) &&this.lonArray.get(iLon,jLat)<=(tempLon+lonLen)){tempNum++;tempTmps += this.tmpArray.get(iLon,jLat);}}}float f = 0f;if(tempNum>0){f = tempTmps/tempNum;}return f;}
}

最终leaflet-vector-scalar.js展示结果如下:

气象NC扇形经纬网格转换成前端要求的等经纬网格相关推荐

  1. 真效率神器,UI稿智能转换成前端代码,准确率极高

    大家好,我是若川.在这充满网络促销活动的几个月,倍感压力的,除了你的口袋,是否还有程序员的发量呢?每年的双十一.双十二购物狂欢节,各大电商平台都会上线让消费者充满购买欲望的活动页面,而这些活动页面大多 ...

  2. python读取nc文件并转换成csv_Python提取netCDF数据并转换为csv文件

    netCDF全称是network Common Data Format(网络通用数据格式),是由美国大学大气研究协会(University Corporation for Atmospheric Re ...

  3. 效率神器!UI 稿智能转换成前端代码

    做前端,不搬砖 大家好,我是若川. 从事前端五年之久,也算见证了前端数次变革,从到DW(Dreamweaver)到H5C3.从JQuery到MVC框架,无数前端大佬在为打造前端完整生态做出努力,由于他 ...

  4. python读取nc文件并转换成csv_如何使用Python读取NetCDF文件并写入CSV

    我的目标是从netcdf文件访问数据并以下列格式写入CSV文件. Latitude Longitude Date1 Date2 Date3 100 200 到目前为止,我已经访问了变量,将标题写入文件 ...

  5. python读取nc文件并转换成csv_使用Python截取nc文件数据保存到CSV文件-Go语言中文社区...

    问题要求: 编写一个函数完成以下任务:截取经度在23°N-40°N,纬度在118°E-131°E范围内各属性不同深度的数据,使用Python中合适的数据结构将截取的数据保存到同名CSV文件中.(nc文 ...

  6. python读取nc文件并转换成csv_python3使用类型转换读取csv文件

    我有两个问题: a)Python csv模块无法正确处理特定csv文件 我在database.csv中有以下数据"AAAAAAAA" , 5.4817, 0.0000, 0.000 ...

  7. 前端“Wed, 22 Sep 2021 15:48:33 GMT“时间转换成“2021-09-22 15:48:33

    前端时间转换问题 "Wed, 22 Sep 2021 15:48:33 GMT"时间转换成"2021-09-22 15:48:33 var d = new Date(va ...

  8. 前端js html转换成pdf可下载打印;前端js可批量生成条形码;前端js可批量生成二维码,生成letter标签

    注意:本文调试的是letter纸尺寸 前端js html转换成pdf可下载打印  html2canvas  + jspdf 前端js生成条形码 Options · lindell/JsBarcode ...

  9. 利用viewbag把数据对象传到前端并转换成json对象,及解决json字符串被转义问题

    利用viewbag把数据对象传到前端并转换成json对象,及解决json字符串被转义问题 参考文章: (1)利用viewbag把数据对象传到前端并转换成json对象,及解决json字符串被转义问题 ( ...

最新文章

  1. 数据呈现 | 20大数据可视化工具测评
  2. 期末考试中微积分的证明题的分析:Taylor级数展开
  3. C++模板:类模板和类模板的友元【C++模板】(57)
  4. 关于web工程项目路径的一些说明
  5. 注册界面演示代码(前端开发)
  6. ubuntu下的linux怎样备份文件,Ubuntu系统如何备份还原?Ubuntu系统备份还原教程
  7. Swift语法3.03(类型Types)
  8. MYSQL同步 Slave_IO_Running: No 或者Slave_SQL_Running: No 解决办法
  9. dubbo 学习资料
  10. Atitit 传感器之道 1. 视觉传感器 摄像头 1 1.1. 一、光线传感器: 1 1.2. 二、距离传感器: 1 1.3.    第一种是震动传感器。 4 1.4.   第二种是声响传感
  11. Spring boot initialization failed for https://start.spring.io
  12. mysqldump批量备份恢复数据脚本
  13. 【转载】使用Winrar对压缩文件进行加密,并且给定解压密码
  14. java mysql聊天室_java实现聊天室的简单实现
  15. 基于MATLAB的GUI界面设计流程
  16. 老男孩python14期全套-老男孩python14期
  17. 8051 系列单片机内部结构
  18. 泛型,泛型的表现,泛型类,泛型方法,泛型接口,通配符,限定
  19. 计算机怎么清理硬盘,怎样清理磁盘?教你清理电脑磁盘的具体步骤
  20. Finclip小程序宿主环境与微信小程序宿主环境

热门文章

  1. 程序实现启用/禁用设备(驱动)enable/disable device with windows api
  2. Android代码中setvisibility失效了?
  3. java模拟cpu返回_Java CPU 占用高 模拟及排查
  4. matlab中的锐度测量,锐度(解析度)MTF定义及测试
  5. SpringBoot整合redis缓存(一)
  6. 基本等离子体波的色散关系
  7. md5加密工具类cookie登陆验证
  8. 郑志远的java学习笔记
  9. python爬虫之获取资源----urllib,requests
  10. MAC中 Texpad编辑