前言
作为计算机专业人士,当我第一次打开雷达数据文件时,整个人都愣住了,一堆复杂的气象雷达术语,仿佛面对外星密码。这可能是许多跨界进入气象雷达领域的计算机人共同的困境。我们精通算法和架构,却对雷达原理一无所知,我们能写出优雅的代码,却看不懂雷达图像中的天气故事。更棘手的是,网络上关于气象雷达编程的资料即零散又专业,让零基础者望而却步 。 本文正是基于这样的背景诞生。它不是一篇纯技术教程,而是一名跨界者的实践经验总结,我将分享如何利用Cinrad库,快速解锁雷达数据处理能力。
一、为什么选择Cinrad库处理气象雷达数据?
作为计算机专业的人士,选择技术栈时,我们会综合评估开发效率、生态兼容性、社区支持和维护成本。在气象雷达数据处理领域,虽然知名的PyART、wradlib等库功能强大通用,但Cinrad库作为专为处理中国新一代天气雷达(CINRAD)数据而生的库,在处理国内业务数据时提供了无与伦比的"开箱即用"体验。
为了更清晰地做出选择,我们可以从以下几个维度进行对比:
评估维度 | Cinrad | PyART/wralib(国际主流) | 对计算机人的意义 |
---|---|---|---|
核心优势 | 本土化、专用化 | 通用化、模块化 | 专用工具vs瑞士军刀 |
数据格式兼容性 | 原生支持 | 需要格式转换或自定义读取器 | Cinrad直接读取 .bin 文件,PyART可能需要先转换为 NETCDF 等格式,增加复杂度和出错可能 |
API设计与易用性 | 高度抽象,几行代码即可完成读取、解析、可视化 | 底层灵活,需要自己组合模块和数据处理流程 | Cinrad像 Scikit-learn ; PyART像 NumPy,更基础更灵活 |
坐标系与投影 | 内置中国区常用投影(如兰伯特投影),直接输出经纬度 | 通常为雷达本身坐标系,需要自行配置地理转换 | 这对于需要在地图上精准定位(如与GIS系统结合)的需求至关重要,Cinrad省去了大量额外步骤 |
文档与社区 | 中文文档,社区较小但作者响应及时 | 英文文档丰富,国际社区活跃 | 对于中文使用者,Cinrad的文档和沟通门槛更低,能更快地获得帮助 |
适用场景 | 处理中国气象局标准的雷达基数据、业务应用、快速分析、科研入门 | 学术研究、算法开发、处理多种国际雷达格式 | 如果你的目标明确是处理国内数据,Cinrad无疑是捷径 |
二、环境配置:安装Cinrad库及依赖
2.1、安装前准备
在开始之前,需要确保已安装Cinrad库及其依赖项。Cinrad支持Python 3.5及以上版本,但版本过高也会出现不兼容的情况,这里强烈推荐使用Python 3.11!
python
#使用pip直接安装Cinrad
pip install cinrad
2.2、验证安装
python
import cinrad
import cartopy
import numpy as np
print(cinrad.__version__) # 打印cinrad版本
print(np.__version__) # 打印numpy版本
print(cartopy.__version__) # 打印cartopy版本
⚠️ 常见问题: 如果出现不兼容情况,通常是Python版本过高导致。本人的Python版本为Python 3.13,与cartopy-0.25.0版本不兼容所致,错误信息如下所示:
2.3、解决方案:使用Conda管理环境
这里采用的办法是在Pycharm中配置Conda。
将Python版本设为3.11,在终端输入:
python
# 创建新环境
conda create -n py311_env python=3.11
# 激活环境
conda activate py311_env
# 安装cartopy
conda install -c conda-forge cartopy
运行结果如图: ✅ 环境配置完成
三、实战开始:读取CINRAD雷达数据
3.1、理解雷达数据格式与获取
中国新一代天气雷达数据通常以二进制格式存储,文件扩展名为 .bin 。这些文件包含了雷达站信息、扫描时间和气象参数等数据。每个文件遵循特定的格式规范,包括文件头、径向数据头和各气象要素的径向数据。 首先,我们需要理解雷达基数据文件的命名规则。以示例文件为例: Z_RADR_I_Z9556_20230617020712_O_DOR_SAD_CAP_FMT.bin.bz2
部分 | 含义 | 说明 |
---|---|---|
Z9556 | 雷达站编号 | 代表具体的气象雷达站 |
20230617020712 | 数据时间 | 格式为年月日时分秒 |
DOR | 数据类型标识 | 表示多普勒雷达数据 |
SAD | 扫描模式 | 表示扇区扫描数据 |
CAP | 数据来源 | 示雷达基数据 |
FMT | 数据格式标识 | 标准格式 |
📢 重要提示::气象雷达基数据属于气象敏感数据,需通过正规渠道获取:
渠道 | 说明 | 适用场景 |
---|---|---|
国家气象信息中心 | 官方数据服务平台 | 历史雷达数据申请 |
中国气象局数据网 | 认证注册用户可申请 | 科研和教育用途 |
省级气象数据中心 | 各省气象局内部平台 | 区域性研究 |
科研合作渠道 | 与科研院所合作 | 学术研究项目 |
🔍 零基础备用方案:读者可在【国家气象科学数据中心】网站注册后,搜索"雷达基数据"进行申请下载。
3.2、读取雷达数据代码实现
python
import cinrad
import matplotlib.pyplot as plt
import numpy as np
from cinrad.visualize import PPI
# 读取雷达数据文件
# 这里是我测试的数据文件目录,请根据实际情况修改
basePath = r"C:\Users\Administrator\Desktop" # 数据存放路径
nFiles = basePath + r"\Z_RADR_I_Z9556_20230617020712_O_DOR_SAD_CAP_FMT.bin.bz2"
f=cinrad.io.StandardData(nFiles)
# 获取雷达基本信息
print("雷达站编号:", f.code)
print("雷达站名:", f.name)
print("扫描时间:", f.scantime)
print("雷达站纬度:",f.stationlat)
print("雷达站经度:",f.stationlon)
print("获取所有仰角列表:",f.angleindex_r)
print("实际仰角度数",f.el)#获取所有仰角的具体角度值(单位:度)
print("可用产品类型:",f.available_product(0))#查询第一个仰角扫描层的可用数据产品
3.3、深入解析数据结构
python
#获取第一个仰角的反射率数据
tilt_number=0
detection_range=230 #探测距离(km)
data_type="REF" #反射率数据
# 获取数据
data = f.get_data(tilt=tilt_number, drange=detection_range, dtype=data_type)
print("=== 雷达数据结构分析 ===")
print("数据对象类型:", type(data))
print("数据维度:", data.dims)
print("数据坐标变量:", list(data.coords.keys()))
print("数据属性:", list(data.attrs.keys()))
# 显示反射率数据统计信息
ref_data = data.REF
print("反射率数据形状:", ref_data.shape)
print("反射率范围: {:.1f} 到 {:.1f} dBZ".format(np.nanmin(ref_data.values), np.nanmax(ref_data.values)))
print("有效数据点数:", np.sum(~np.isnan(ref_data.values)))
# 显示经纬度范围
print("经度范围: {:.3f}° 到 {:.3f}°".format(
np.nanmin(data.longitude.values), np.nanmax(data.longitude.values)))
print("纬度范围: {:.3f}° 到 {:.3f}°".format(
np.nanmin(data.latitude.values), np.nanmax(data.latitude.values)))
print("高度范围: {:.1f} 到 {:.1f} 米".format(
np.nanmin(data.height.values), np.nanmax(data.height.values)))
四、雷达数据可视化
4.1、生成平面位置显示(PPI)图
python
#生成PPI图像
fig=plt.figure(figsize=(8,8))#设置图形尺寸为8*8英寸
# 创建PPI显示对象
display=PPI(data,fig)
display.plot_range_rings([50,100,150,200,250],color="white", linewidth=1) #添加距离圈
display.gridlines(draw_labels=True, linewidth=1, color="white") #画经纬度网格线
#设置图形属性
plt.title(f'product:{data_type} code:{f.code} scantime:{f.scantime} tilt:{tilt_number}')
import cartopy.crs as ccrs
#标注雷达站点所在位置
display.geoax.scatter(x=f.stationlon, y=f.stationlat, s=500, c="r", marker=".", transform=ccrs.PlateCarree())
plt.show()
4.2、运行结果展示
图像解析: 彩色区域表示不同强度的降水回波 同心圆表示距离圈(每50公里一个) 红色圆点表示雷达站位置 颜色条显示反射率强度(dBZ)
五、完整代码展示
python
import cinrad
import matplotlib.pyplot as plt
import numpy as np
from cinrad.visualize import PPI
# 读取雷达数据文件
# 这里是我测试的数据文件目录,请根据实际情况修改
basePath = r"C:\Users\Administrator\Desktop" # 数据存放路径
nFiles = basePath + r"\Z_RADR_I_Z9556_20230617020712_O_DOR_SAD_CAP_FMT.bin.bz2"
f=cinrad.io.StandardData(nFiles)
# 获取雷达基本信息
print("雷达站编号:", f.code)
print("雷达站名:", f.name)
print("扫描时间:", f.scantime)
print("雷达站纬度:",f.stationlat)
print("雷达站经度:",f.stationlon)
print("获取所有仰角列表:",f.angleindex_r)
print("实际仰角度数",f.el)#获取所有仰角的具体角度值(单位:度)
print("可用产品类型:",f.available_product(0))#查询第一个仰角扫描层的可用数据产品
#获取第一个仰角的反射率数据
tilt_number=0
detection_range=230 #探测距离(km)
data_type="REF" #反射率数据
# 获取数据
data = f.get_data(tilt=tilt_number, drange=detection_range, dtype=data_type)
print("=== 雷达数据结构分析 ===")
print("数据对象类型:", type(data))
print("数据维度:", data.dims)
print("数据坐标变量:", list(data.coords.keys()))
print("数据属性:", list(data.attrs.keys()))
# 显示反射率数据统计信息
ref_data = data.REF
print("反射率数据形状:", ref_data.shape)
print("反射率范围: {:.1f} 到 {:.1f} dBZ".format(np.nanmin(ref_data.values), np.nanmax(ref_data.values)))
print("有效数据点数:", np.sum(~np.isnan(ref_data.values)))
# 显示经纬度范围
print("经度范围: {:.3f}° 到 {:.3f}°".format(
np.nanmin(data.longitude.values), np.nanmax(data.longitude.values)))
print("纬度范围: {:.3f}° 到 {:.3f}°".format(
np.nanmin(data.latitude.values), np.nanmax(data.latitude.values)))
print("高度范围: {:.1f} 到 {:.1f} 米".format(
np.nanmin(data.height.values), np.nanmax(data.height.values)))
#生成PPI图像
fig=plt.figure(figsize=(8,8))#设置图形尺寸为8*8英寸
#创建PPI显示对象
display=PPI(data,fig)
display.plot_range_rings([50,100,150,200,250],color="white", linewidth=1) #添加距离圈
display.gridlines(draw_labels=True, linewidth=1, color="white") #画经纬度网格线
#设置图形属性
plt.title(f'product:{data_type} code:{f.code} scantime:{f.scantime} tilt:{tilt_number}')
import cartopy.crs as ccrs
#标注雷达站点所在位置
display.geoax.scatter(x=f.stationlon, y=f.stationlat, s=500, c="r", marker=".", transform=ccrs.PlateCarree())
plt.show()
总结
通过本文的介绍,我们已经掌握了使用Cinrad库处理气象雷达数据的基本流程: 1.环境配置 : 正确配置Python 3.11+ Cinrad环境 2.数据读取 :使用cinrad.io.StandardData读取雷击基数据文件 3.数据解析 :深入理解雷达数据结构和属性 4.可视化:生成平面位置显示(PPI)图
大家在学习雷达图像处理时还遇到了哪些"劝退"的难题?欢迎在评论区讨论,我会尽力解答!如果大家需要,下一篇我可以深入讲解如何使用Cartopy生成地理参考图、绘制组合反射率或者是雷达数据的三维可视化。 欢迎点赞、收藏、关注,您的支持是我持续创作的最大动力!
本文首次发布在CSDN平台。