气象数据NC、grb2解析成矢量json、CMIS、MICPS及图片应用到webgis

一、基础概念

气象数据通常以多种格式存储和交换,以适应不同的应用需求和处理工具。以下是一些常见的气象数据格式及其转换方法的概述:

常见气象数据格式

1. NetCDF(Network Common Data Form):一种自描述、自包含的数据格式,广泛用于存储气象和气候模型输出、观测数据等。NetCDF支持多维度数组、属性和变量,便于跨平台共享。

2. GRIB(GRIdded Binary):主要用于气象预报产品,包括GRIB1和GRIB2两种版本。它以高效的方式存储大量的气象格点数据,如温度、风速等,是气象预报中心之间交换数据的标准格式。

3. HDF(Hierarchical Data Format):类似于NetCDF,支持复杂的数据结构,适用于大规模科学数据集的存储和分发。HDF4和HDF5是两个主要版本。

4. CSV(Comma-Separated Values):简单的文本格式,易于阅读和处理,常用于数据交换,但缺乏自描述性,不包含元数据。

5. GeoTIFF:一种地理空间图像格式,用于存储栅格数据,如卫星图像或气象地图,包含地理坐标信息。

6. BUFR(Binary Universal Form for the Representation of Meteorological Data):国际气象组织推荐的一种二进制编码格式,特别适用于气象观测数据的交换。

数据格式转换方法

1. 使用专业软件:

•Panoply:NASA开发的免费软件,可以打开、查看和转换NetCDF、HDF、GRIB等格式数据。•NCAR Command Language (NCL):提供丰富的脚本语言功能,用于处理NetCDF、GRIB等气象数据。

•GDAL/OGR:开源地理空间库,提供了广泛的格式转换能力,支持NetCDF、HDF、GeoTIFF等格式的转换。

2. 编程语言库:

•Python: 利用netCDF4, pygrib, h5py等库进行数据读写和格式转换。xarray库提供了更高级的数据结构,方便处理NetCDF和GRIB数据。

•MATLAB:内置了对NetCDF、HDF的读写支持,也可通过第三方工具箱处理其他格式。

•R语言:使用ncdf4、raster、rgdal等包处理NetCDF、GRIB、GeoTIFF等格式。

3. 在线转换工具:

虽然不如上述方法灵活,但存在一些在线工具,允许用户上传文件并转换为不同格式,不过这类工具在处理大型气象数据集时可能受限。进行数据格式转换时,需注意保留数据的完整性和准确性,特别是元数据信息,以确保转换后的数据在后续分析中仍然有效。

二、实践应用

关键代码实现

package com.netcdf.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.*;import static com.netcdf.util.NcUtil.*;@Controller
@RequestMapping(value = "/ReadGridNc")public class ReadGridNcData {//http://localhost:8087/NetcdfServer/ReadGridNc/getNcData?FilePath=20210708_2021070804.nc&FilterBound=&valField=UGRD_10maboveground/**** @param FilePath* @param FilterBound* @param valField* @return*/@RequestMapping(value = "/getNcData", method = RequestMethod.GET)public @ResponseBodyMap GetNcData(String FilePath,String FilterBound,String valField) {Map map = AnalysisNC(FilePath, FilterBound,valField,1);return map;}//http://localhost:8087/NetcdfServer/ReadGridNc/GetNcWindData?FilePath=2023042323.grb2/**** @param FilePath* @return*/@RequestMapping(value = "/GetNcWindData", method = RequestMethod.GET)public @ResponseBodyJSONArray GetNcWindData(String FilePath) {String map = AnalysisNcWind(FilePath);return JSON.parseArray(map);}//http://localhost:8088/NetcdfServer/ReadGridNc/getNcDataSurface?FilePath=2022090212.nc&FilterBound=&valField=PRES_surface&intvRanges=0,100000,10005,100010,100015&boundPath=1&isIDW=true&isClip=false/**** @param FilePath* @param FilterBound* @param valField* @return*/@RequestMapping(value = "/getNcDataSurface", method = RequestMethod.GET)public @ResponseBodyString GetNcDataSurface(String FilePath,String FilterBound,String valField,String intvRanges,String boundPath,boolean isIDW,boolean isClip) {String[] Ranges=intvRanges.substring(0,intvRanges.length()).split(",");double[] dataInterval = new double[Ranges.length];for(int i=0;i<Ranges.length;i++){dataInterval[i]=Double.valueOf(Ranges[i]);if( i == 1 && dataInterval[i] == 0.0){dataInterval[i] = 0.0001;}}Map map = AnalysisNC(FilePath, FilterBound,valField,1);if(map!=null) {String strGeojson = nc2EquiSurface(map, dataInterval,isClip,boundPath,isIDW);return strGeojson;}return "";}//http://localhost:8088/NetcdfServer/ReadGridNc/getNcDataSurface1?FilePath=wrf_ll.nc&FilterBound=&valField=RH2M&intvRanges=0,100000,10005,100010,100015&boundPath=1&isIDW=true&isClip=false//http://localhost:8088/NetcdfServer/ReadGridNc/getNcDataSurface1?FilePath=wrf_ll.nc&FilterBound=&valField=RH2M&intvRanges=0,70,75,80,85,90,95&boundPath=1&isIDW=false&isClip=false/**** @param FilePath* @param FilterBound* @param valField* @return*/@RequestMapping(value = "/getNcDataSurface1", method = RequestMethod.GET)public @ResponseBodyString GetNcDataSurface1(String FilePath,String FilterBound,String valField,String intvRanges,String boundPath,boolean isIDW,boolean isClip) {String[] Ranges=intvRanges.substring(0,intvRanges.length()).split(",");double[] dataInterval = new double[Ranges.length];for(int i=0;i<Ranges.length;i++){dataInterval[i]=Double.valueOf(Ranges[i]);if( i == 1 && dataInterval[i] == 0.0){dataInterval[i] = 0.0001;}}Map map = AnalysisNC1(FilePath, FilterBound,valField,3);
//        Map map = AnalysisNC1(FilePath, FilterBound,valField);if(map!=null) {String strGeojson = nc2EquiSurface1(map, dataInterval,isClip,boundPath,isIDW);return strGeojson;}return "";}//http://localhost:8088/NetcdfServer/ReadGridNc/getNcDataMICPS?FilePath=wrf_ll.nc&FilterBound=&valField=RH2M&intvRanges=0,70,75,80,85,90,95&boundPath=1&isIDW=false&isClip=false/**** @param FilePath* @param FilterBound* @param valField* @return*/@RequestMapping(value = "/getNcDataMICPS", method = RequestMethod.GET)public @ResponseBodyString GetNcDataMICPS(String FilePath,String FilterBound,String valField,String intvRanges,String boundPath,boolean isIDW,boolean isClip) {String[] Ranges=intvRanges.substring(0,intvRanges.length()).split(",");double[] dataInterval = new double[Ranges.length];for(int i=0;i<Ranges.length;i++){dataInterval[i]=Double.valueOf(Ranges[i]);if( i == 1 && dataInterval[i] == 0.0){dataInterval[i] = 0.0001;}}Map map = AnalysisNC1(FilePath, FilterBound,valField,1);
//        Map map = AnalysisNC1(FilePath, FilterBound,valField);if(map!=null) {StringBuilder strGeojson = new StringBuilder();strGeojson.append("diamond 4 2022年4月1日GFS地面相对湿度3小时预报\n" +"    2022    4    1    0   3   2   0.5  -0.5 \n" +"    96.5 106.5 29.5 20.5 \n" +"    1001 901 5 -50 50 1 0\n");strGeojson.append(map.get("val").toString().replace("[","").replace("]","").replaceAll(","," "));return strGeojson.toString();}return "";}//http://localhost:8088/NetcdfServer/ReadGridNc/getNcDataCMISS?FilePath=wrf_ll.nc&FilterBound=&valField=RH2M&intvRanges=0,70,75,80,85,90,95&boundPath=1&isIDW=false&isClip=false/**** @param FilePath* @param FilterBound* @param valField* @return*/@RequestMapping(value = "/getNcDataCMISS", method = RequestMethod.GET)public @ResponseBodyString GetNcDataCMISS(String FilePath,String FilterBound,String valField,String intvRanges,String boundPath,boolean isIDW,boolean isClip) {String[] Ranges=intvRanges.substring(0,intvRanges.length()).split(",");double[] dataInterval = new double[Ranges.length];for(int i=0;i<Ranges.length;i++){dataInterval[i]=Double.valueOf(Ranges[i]);if( i == 1 && dataInterval[i] == 0.0){dataInterval[i] = 0.0001;}}Map map = AnalysisNC1(FilePath, FilterBound,valField,1);
//        Map map = AnalysisNC1(FilePath, FilterBound,valField);if(map!=null) {StringBuilder strGeojson = new StringBuilder();strGeojson.append("{\"returnCode\":\"0\",\"returnMessage\":\"Query Succeed\",\"startLat\":29.5,\"startLon\":96.5,\"endLat\":20.5,\"endLon\":106.5,\"latCount\":901,\"lonCount\":1001,\"latStep\":-0.01,\"lonStep\":0.01,\"requestParams\":\"minlat=20.5&time=20190810000000&fcstele=VVP&datacode=NAFP_FOR_FTM_HIGH_JAP_NEHE&maxlat=29.5&fcstlevel=850&maxlon=106.5&validtime=0&minlon=96.5\",\"requestTime\":\"2019-08-20 08:02:24\",\"responseTime\":\"2019-08-20 08:02:24\",\"takeTime\":\"0.022\",\"fieldNames\":\"湿度\",\"fieldUnits\":\"Pa*s^-1\",\"DS\":[");strGeojson.append(map.get("val").toString());strGeojson.append("]}");return strGeojson.toString();}return "";}//http://localhost:8088/NetcdfServer/ReadGridNc/getNcDataSurfaceWind?FilePath=2024050914.nc&FilterBound=&intvRanges=0,2,4,6,8,10&boundPath=1&isIDW=true&isClip=false/**** @param FilePath* @param FilterBound* @param valField* @return*/@RequestMapping(value = "/getNcDataSurfaceWind", method = RequestMethod.GET)public @ResponseBodyString GetNcDataSurfaceWind(String FilePath,String FilterBound,String valField,String intvRanges,String boundPath,boolean isIDW,boolean isClip) {String[] Ranges=intvRanges.substring(0,intvRanges.length()).split(",");double[] dataInterval = new double[Ranges.length];for(int i=0;i<Ranges.length;i++){dataInterval[i]=Double.valueOf(Ranges[i]);if( i == 1 && dataInterval[i] == 0.0){dataInterval[i] = 0.0001;}}//导出图片AnalysisNCWindyToPng(FilePath, FilterBound,"UGRD_10maboveground","VGRD_10maboveground");
//        Map map = AnalysisNCWindy(FilePath, FilterBound,"UGRD_10maboveground","VGRD_10maboveground");//        if(map!=null) {
//            String strGeojson = nc2EquiSurface(map, dataInterval,isClip,boundPath,isIDW);
//            return strGeojson;
//        }return "nc";}//http://localhost:8088/NetcdfServer/ReadGridNc/getGribDataSurfaceWind?FilePath=2024050914.grb2&FilterBound=&intvRanges=0,1,2,3,4,5,6,7,8,9,10,11,12&boundPath=1&isIDW=true&isClip=false/**** @param FilePath* @param FilterBound* @param valField* @return*/@RequestMapping(value = "/getGribDataSurfaceWind", method = RequestMethod.GET)public @ResponseBodyString GetGribDataSurfaceWind(String FilePath,String FilterBound,String valField,String intvRanges,String boundPath,boolean isIDW,boolean isClip) {String[] Ranges=intvRanges.substring(0,intvRanges.length()).split(",");double[] dataInterval = new double[Ranges.length];for(int i=0;i<Ranges.length;i++){dataInterval[i]=Double.valueOf(Ranges[i]);if( i == 1 && dataInterval[i] == 0.0){dataInterval[i] = 0.0001;}}//导出图片
//        AnalysisNCWindyToPng(FilePath, FilterBound,"UGRD_10maboveground","VGRD_10maboveground");AnalysisGribWindyToPng(FilePath, FilterBound,"u-component_of_wind_height_above_ground","v-component_of_wind_height_above_ground");return "grib";}}
<!DOCTYPE html>
<html>
<head><title>Layers Control Tutorial - Leaflet</title><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0"><link rel="shortcut icon" type="image/x-icon" href="docs/images/favicon.ico" /><link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin=""/><script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js" integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew==" crossorigin=""></script><style>html, body {height: 100%;margin: 0;}#map {width: 1000px;height: 700px;}</style></head>
<body><div id='map'></div><script>var grayscaleLayer= L.tileLayer('http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer/tile/{z}/{y}/{x}', {id: 'map11',maxZoom: 16,minZoom: 4});var map = L.map('map', {minZoom: 5,maxZoom: 12,center: [21, 100],zoom: 10,zoomDelta: 0.5,//点击+-按钮的放缩刻度尺度,默认值1zoomSnap: 0.5,//地图能放缩的zoom的最小刻度尺度,默认值1fullscreenControl: false,//全屏控件,不显示zoomControl: false,//放大缩小控件,不显示attributionControl: false//右下角属性控件,不显示});map.addLayer(grayscaleLayer);var imageBounds = [[20.5, 96.5], [29.41, 106.5]];//图片的经纬度范围,西南角点,东北角点(纬度、经度)var imageUrl='pixel_art.png';//图片的地址var imageLayer =L.imageOverlay(imageUrl, imageBounds,{opacity:0.8});//opacity是透明度map.addLayer(imageLayer);//如果imageLayer已经创建,后续只需要切换url即可if(imageLayer!=null){imageLayer.setUrl(imageUrl);}
</script></body>
</html>

转换成图片成果

示例调用实现

转换成矢量json成果

转换成MICPS成果

转换成CMIS成果

 前端可视效果

成果应用展示

参照windy配置可视化实现

 如果对您有所帮助,请点赞打赏支持!

技术合作交流qq:2401315930

最后分享一下地图下载器设计及下载地址:

链接:https://pan.baidu.com/s/1RZX7JpTpxES-G7GiaVUxOw 
提取码:61cn

地图下载器代码结构设计及功能实现_地图下载管理器解析-CSDN博客

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

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

相关文章

如何在MATLAB中创建各种常用的图形

本文将介绍如何在MATLAB中创建各种常用的图形。将涵盖以下内容&#xff1a; 基本的二维图形 折线图&#xff08;Line Plot&#xff09;散点图&#xff08;Scatter Plot&#xff09;条形图&#xff08;Bar Plot&#xff09;面积图&#xff08;Area Plot&#xff09; 三维图形 三…

WACV2024论文3D相关速览48篇

WACV2024 3D相关论文阅读 Paper1 Self-Supervised Edge Detection Reconstruction for Topology-Informed 3D Axon Segmentation and Centerline Detection 摘要小结: 许多基于机器学习的轴突追踪方法依赖于带有分割标签的图像数据集。这需要领域专家的手动标注&#xff0c;既…

R语言——绘图与数据可视化

1、练习将25个点的符号绘制出来&#xff0c;然后用rainbow()返回25个颜色&#xff0c;后5个符号形状的背景颜色用蓝色填充&#xff0c;图的标题为"符号图"&#xff0c;x轴标题为符号索引&#xff0c;y轴标题为符号形状。 2、根据员工的销售业绩画饼状图&#xff0c;添…

[保姆级教程]在uniapp中使用vant框架

文章目录 导文安装 Vant在uniapp项目中的pages.json中配置easycom&#xff0c;实现组件的自动按需引入&#xff1a;在页面中使用Vant Weapp组件&#xff0c;例如使用按钮组件&#xff08;Button&#xff09;&#xff1a;其他安装报错官网地址 导文 在 uni-app 中使用 Vant 框架…

关于OS中逻辑地址与物理地址转换

首先将逻辑地址134D从十六进制转为2进制 0001 0011 0100 1101 1&#xff09;1K的时候对应2的10次方 页面大小占10位 从后往前数 0001 00 || 11 0100 1101 前面的转为十进制为4 对应页号4内容1A转为2进制01 1010将这个替换原来的前六位数字 即0110 1011 0100 1101 再转换为…

智慧工厂监控可视化解决方案(160页WORD)

方案介绍&#xff1a; 本智慧工厂监控可视化解决方案通过集成先进的物联网和大数据技术&#xff0c;为制造业企业提供了全面的数字化转型支持。通过实时监控、数据分析、可视化展示等功能&#xff0c;帮助企业提升生产效率、降低运营成本、优化产品质量和能源利用率&#xff0…

C# 语言在AGI 赛道上能做什么

自从2022年11月OpenAI正式对外发布ChatGPT依赖&#xff0c;AGI 这条赛道上就挤满了重量级的选手&#xff0c;各大头部公司纷纷下场布局。原本就在机器学习、深度学习领域占据No.1的Python语言更是继续稳固了自己AI一哥的位置。凭借着Microsoft 和 OpenAI 长期以来一直是紧密相连…

【CT】LeetCode手撕—300. 最长递增子序列

目录 题目1- 思路2- 实现⭐300. 最长递增子序列——题解思路 3- ACM 实现 题目 原题连接&#xff1a;300. 最长递增子序列 1- 思路 模式识别&#xff1a;最长递增子序列——> 利用动规五部曲 解决 ——> 借助 i 和 j 指针&#xff0c;其中 j < i 动规五部曲 1.定义…

【功能详解】银河麒麟操作系统“安全启动”是如何发挥作用的?

2023年12月&#xff0c;财政部、工信部发布了7项信息类产品《政府采购需求标准》&#xff0c;为包括操作系统在内多项产品的政府集中采购提供政策支撑。其中&#xff0c;安全、可信作为国产操作系统的基本要求备受关注。 安全体系的构建离不开操作系统本身的硬实力&#xff0c…

LabVIEW项目管理中如何平衡成本、时间和质量

在LabVIEW项目管理中&#xff0c;平衡成本、时间和质量是实现项目成功的关键。通过制定详细的项目计划、合理分配资源、严格控制进度、进行质量保证和灵活应对变化&#xff0c;项目管理者可以有效地协调这三者的关系&#xff0c;确保项目按时、按质、按预算完成。 1. 制定详细…

CVPR最佳论文:谷歌基于Spectral Volume从单图生成视频

一、摘要&#xff1a; 论文&#xff1a;Generative Image Dynamics&#xff0c;https://arxiv.org/pdf/2309.07906 项目主页&#xff1a;https://generative-dynamics.github.io/ 本文提出了一种新颖的方法来模拟场景运动的图像空间先验。通过从真实视频序列中提取的自然振荡…

高考志愿填报:选择好专业还是好学校?

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 高考志愿填报&#xff1a;选择好专业还是好学校&#xff1f; 每年高考结束后&#xff0c;考生和家长面临的一个…

MEMS环境传感器生产测试的挑战与未来趋势

微机电系统 (MEMS) 环境传感器无处不在&#xff0c;默默地支撑着我们日常生活中众多设备的功能。从智能手机和可穿戴设备到智能家居和工业自动化&#xff0c;这些微型产品可以测量温度、压力、湿度和大量其他环境参数。 由于环境监测需求不断增长以及空气质量严格法规的实施&am…

Ubuntu 18.04 安装 PCL 1.14.1

在进行科研项目时&#xff0c;我们常常需要将 C 和 Python 结合起来编程。然而&#xff0c;每次将 PCL&#xff08;Point Cloud Library&#xff09;的内容添加到 CMakeLists.txt 文件中时都会报错。在深入分析后&#xff0c;我们推测可能是当前使用的 PCL 1.8 版本与现有程序不…

Instagram APIj接口——快速获取Ins帖子媒体内容下载链接

一、引言 在社交媒体蓬勃发展的今天&#xff0c;Instagram已成为用户分享照片、视频和精彩瞬间的首选平台。然而&#xff0c;对于很多用户来说&#xff0c;想要保存或分享Instagram上的精彩内容却常常遇到困扰。为了解决这个问题&#xff0c;我们精心打造了一款全新的Instagra…

视频云沉浸式音视频技术能力探索与建设

概述 随着传输技术、显示技术与算力的持续提升&#xff0c;用户对于音视频体验的需求在提高&#xff0c;各家设备厂商也在探索和推出对应的技术与产品。打造空间感的空间视频与空间音频是其中最为关键的2项技术&#xff0c;bilibili视频云在这两项技术领域也进行了相关代探索与…

优惠卷秒杀(并发问题)

Redis实战篇 | Kyles Blog (cyborg2077.github.io) 目录 一、Redis实现全局唯一id 二、添加优惠卷 三、实现秒杀下单 四、解决超卖问题&#xff08;库存为负&#xff09; 乐观锁解决超卖问题&#xff08;CAS法&#xff09; 五、实现一人一单 ​编辑 悲观锁解决一人一单问题…

自主可控的工业操作系统

supOS是蓝卓自主研发、拥有自主知识产权的工业操作系统&#xff0c;向下可以连接各种设备和信息系统&#xff0c;将所有数据汇聚到“统一的底座”&#xff0c;向上可以打通各种各样的应用系统&#xff0c;各类生态企业可以在系统之上打造出丰富的工业APP&#xff0c;让我们的工…

有没有屏幕悬浮翻译软件?打开窗口即可实时翻译

随着#高考结束该出发看世界了#这一话题的火热&#xff0c;对于不能远行的朋友&#xff0c;网上冲浪是了解世界的好方式。 然而&#xff0c;面对外语网页、资料或视频&#xff0c;英语不流利的小伙伴可能会有些困扰。别急&#xff0c;悬浮翻译软件能帮你将屏幕上的外语文字即时…

从WebM到MP3:利用Python和wxPython提取音乐的魔法

前言 有没有遇到过这样的问题&#xff1a;你有一个包含多首歌曲的WebM视频文件&#xff0c;但你只想提取其中的每一首歌曲&#xff0c;并将它们保存为单独的MP3文件&#xff1f;这听起来可能有些复杂&#xff0c;但借助Python和几个强大的库&#xff0c;这个任务变得异常简单。…