简介面向气象数据处理、雷达产品开发与教学科研人员的CINRAD雷达基数据格式参考文档聚焦SA/SB与CA/CB两类雷达的二进制存储规范帮助读者解决基数据解析、字段定位与解码换算中的实际问题。资源包共1个doc文件约92KB以字节顺序表形式逐项列出雷达信息头、径向数据收集时间、儒略日、不模糊距离、方位角与仰角编码、径向数据状态、体扫仰角数、反射率与多普勒数据的首库距离、库长、库数及数据指针等字段并给出反射率、速度、谱宽的编码公式与无回波、距离模糊的取值约定。文档还说明每个体扫单独存为一个文件、径向数据按仰角由低到高排列、径向长度固定为2432字节以及SA/SB与CA/CB在库长和最大库数上的差异。已有2806人学习适合需要对照字节表编写解析程序或核对数据结构的读者查阅。1. 雷达基数据格式一份被二进制藏起来的天气日记如果你打开过一个雷达基数据文件第一反应大概率是——这玩意儿怎么全是乱码没有表头、没有逗号分隔、没有 JSON 的花括号用文本编辑器打开就是一屏看不懂的字符。可它偏偏记录着一整场天气过程的全部细节哪个方向、哪个高度、多远距离上回波有多强、风在往哪吹、气流有多乱。通俗地说雷达基数据格式就是一套“约定”雷达把探测结果按固定顺序、固定字节长度写进文件读的人必须拿着同一份约定一个字节一个字节地对号入座才能把二进制还原成反射率、速度、谱宽这些我们能看懂的量。它像一本没有目录的账本页码是死的第几页记什么完全靠规矩。搞懂这套格式你才能把雷达的原始观测变成图、变成数据、变成能判断天气的东西搞不懂文件就永远是个黑匣子。这一篇就围绕 CINRAD SA/SB 与 CA/CB 这两类雷达的基数据格式把“它是什么、为什么这么设计、容易混在哪”讲清楚。2. 为什么雷达数据要按字节死磕固定长度背后的取舍2.1 一个体扫一个文件一条径向固定 2432 或 4132 字节先说存储方式。每个体扫一次完整的立体扫描存成一个独立文件文件内部按径向数据一条一条顺序排列从低仰角开始一路排到高仰角结束。所谓径向就是雷达天线在某个方位角上“扫”出去的那一条射线这条射线上每隔一段距离取一个采样点这些点叫距离库。关键在于每条径向的长度是固定的。SA/SB 雷达一条径向固定 2432 字节CA/CB 雷达固定 4132 字节。固定长度意味着什么意味着你不需要任何分隔符只要知道第几条径向就能用“起始字节 序号 × 长度”直接跳到它。打个比方这就像一栋每层户型完全一样的楼找 302 房间不用逐户敲门算一下楼梯层数就行。代价是灵活性——不管这条径向上实际有多少有效数据空间都得按最大值预留浪费是必然的但换来的是读取时的确定性和速度。2.2 28 字节信息头整条径向的“身份证”每条径向开头都有 28 字节的雷达信息头里面塞满了描述这条径向的元信息。别小看这 28 字节它是解读后面所有数据的钥匙。举几个最常用的字段字节位置含义编码方式15-16数据类型标识1 表示雷达数据29-32径向收集时间毫秒自 00:00 起算33-34儒略日自 1970 年 1 月 1 日起算35-36不模糊距离数值 / 10 千米37-38方位角[数值/8] × [180/4096] 度41-42径向数据状态0 首条、1 中间、2 末条、3 体扫首条、4 体扫末条43-44仰角[数值/8] × [180/4096] 度45-46体扫内仰角数直接读数65-66反射率数据指针偏离信息头的字节数71-72多普勒速度分辨率2 表示 0.5 米/秒4 表示 1.0 米/秒73-74体扫模式 VCP11/21 降水31/32 晴空89-90Nyquist 速度数值 / 100 米/秒这里最容易被忽略的是“指针”字段。反射率、速度、谱宽三块数据在径向里的起始位置不是写死的而是由 65-66、67-68、69-70 三个双字节指针告诉你“从信息头往后数多少字节开始”。为什么要这么设计因为不同雷达、不同模式、不同分辨率下三块数据的长度会变用指针比用固定偏移更稳。读的时候先读指针再按指针跳过去这是正确姿势。2.3 编码不是直读数值要经过一次“翻译”原始字节里存的不是物理量本身而是编码后的整数。以反射率为例SA/SB 雷达的编码方式是(数值 - 2) / 2 - 32 dBZ。也就是说你读到一个字节值 66先减 2 得 64除以 2 得 32再减 32 得 0 dBZ。速度的编码分两种分辨率 0.5 米/秒时是(数值 - 2) / 2 - 63.5分辨率 1.0 米/秒时是(数值 - 2) - 127。谱宽则统一按(数值 - 2) / 2 - 63.5处理。还有两个特殊值必须记住数值为 0 表示无回波低于信噪比阈值数值为 1 表示距离模糊。这两个值不能套公式算得单独判断否则会算出毫无意义的物理量。很多初学者第一次读数据发现图上一片诡异的负值八成就是忘了处理这两个哨兵值。2.4 为什么库长和库数要分波段定死反射率和多普勒速度、谱宽用的距离库长不一样这是设计上的必然。SA/SB 雷达反射率库长 1000 米、最大 460 个库速度和谱宽库长 250 米、最大 920 个库CA/CB 雷达反射率库长 500 米、最大 800 个库速度和谱宽库长 125 米、最大 1600 个库。反射率要看得远库长就粗速度和谱宽要看得细库长就短、库数就多。这就像用望远镜看远景和用放大镜看近物目的不同刻度自然不同。读数据前先确认自己手上是哪个波段库数设错了整张图会错位。3. 两类雷达格式的区别SA/SB 与 CA/CB 到底差在哪3.1 径向长度和库数2432 对 4132 的连锁反应最直观的差别是径向长度SA/SB 是 2432 字节CA/CB 是 4132 字节。这不是随便定的而是由库数决定的。SA/SB 反射率最多 460 个库、速度谱宽最多 920 个库加起来约 2300 字节的数据区加上信息头和保留区凑成 2432CA/CB 反射率 800 库、速度谱宽各 1600 库数据区约 4000 字节凑成 4132。所以看到文件里每条径向的长度基本就能反推是哪类雷达。这个差别会连锁影响到读取程序。原文给出的数组定义里RGates、VGates、WGates三个常量就是按波段切换的开关读 S 波段时RGates 460、VGates 920、WGates 920读 C 波段时改成RGates 800、VGates 1600、WGates 1600。改错一个数数组就越界或者读不全这是血泪经验里最常见的一类翻车。// 读取 S 波段基数据时的库数定义 const int RGates 460; // 反射率距离库数 const int VGates 920; // 速度距离库数 const int WGates 920; // 谱宽距离库数 // 若要读取 C 波段基数据改为 // const int RGates 800; // const int VGates 1600; // const int WGates 1600;上面这段定义放在头文件里本质是把“波段”这个物理事实翻译成“数组维度”这个程序事实。参数说明很直白RGates 对应反射率那条数组的第三维长度VGates 和 WGates 对应速度和谱宽。改的时候三个一起改别只改一个否则三块数据在内存里对不齐。3.2 数据区布局指针相同偏移不同两类雷达的信息头字段含义基本一致指针字段的位置也一样65-66 反射率、67-68 速度、69-70 谱宽但指针指向的实际偏移值不同因为前面的信息头加保留区长度虽然都是 128 字节左右后面数据区的排布却随库数变化。SA/SB 的反射率数据从第 129 字节开始速度从R1开始谱宽从V1开始CA/CB 同样是 129 字节起但每块的长度拉长到 800、1600、1600。读的时候永远以指针为准不要硬编码“反射率一定在 129”虽然多数情况如此但按指针走才是稳的。3.3 仰角层数的坑扫两次不等于两层这是两类雷达共有的一个易混点但特别值得单独拎出来说。SA、SB、CB 雷达在低层每个仰角上会扫描两次比如 21 扫描模式的 VCP 仰角序列是 0.5、0.5、1.5、1.5、2.4、3.4、4.3、6.0、9.9、14.6、19.5一共 11 次 PPI 扫描。但程序保存时0.5 和 1.5 各扫的两次被合并记为一个仰角层所以Elvation[]数组里只有 9 个有效元素0.5、1.5、2.4、3.4、4.3、6.0、9.9、14.6、19.5。基数据实际有效层数是 9 层不是 11 层。如果你按“扫了几次就是几层”去分配数组后面对不上号图会叠在一起或者缺层。正确做法是看径向数据状态字段状态 0 是该仰角第一条状态 2 是最后一条状态 3 是体扫第一条状态 4 是体扫最后一条。靠这些状态位来切层比数扫描次数可靠得多。3.4 无效值与距离折叠-999.0 和 999.0 不是随便定的程序里把无效数据标记为 -999.0距离折叠标记为 999.0。为什么用这两个数因为它们远离真实物理量的合理范围——反射率再低也不会到 -999 dBZ速度再大也不会到 999 米/秒用这种极端值当“旗标”后续判断时一眼就能认出来不会和真实观测混淆。这跟数据库里用 NULL 表示缺失是一个思路拿一个不可能出现的值占位比额外维护一个布尔数组省事。读数据时先把这两个值识别出来再做插值或绘图否则它们会把色标拉爆整张图糊成一团。4. 常见误区与易混概念读基数据时最容易踩的五个坑4.1 把“字节位置”当成“数组下标”易混点信息头里写“35-36 字节是不模糊距离”有人就直接拿数组第 35 个元素去读。为什么混字节位置是从 1 开始数的文件偏移数组下标是从 0 开始的内存位置两者差一位而且多字节字段还涉及高低字节顺序。怎么区分记住“文件偏移从 1 数、数组下标从 0 数”读双字节字段时先确认字节顺序原文明确是双字节顺序再拼成一个整数。差一位的后果是读出来的方位角永远偏一点图看着“差不多”但就是不对。4.2 把“径向序号”当成“方位角”易混点信息头里有“当前仰角内径向数据序号”39-40 字节也有“方位角”37-38 字节两个都是数字容易拿来就用。为什么混序号是第几条径向方位角是天线指向多少度前者是计数后者是角度。怎么区分序号用来排序和切层方位角用来定位。程序里MaxRads按“每度保存一个径向”来设说明最终要的是方位角不是序号。用序号当角度图会整体旋转错位。4.3 把“扫描次数”当成“仰角层数”易混点前面说过低层仰角扫两次有人就认为层数等于扫描次数。为什么混物理上确实扫了两次但数据组织上合并为一层。怎么区分看Elvation[]的有效元素个数或者靠径向状态位切层。以 21 模式为例11 次扫描对应 9 层这个换算关系要刻在脑子里。4.4 把“反射率库长”套到“速度库长”上易混点反射率库长 1000 米S 波段速度库长 250 米有人图省事全用 1000 米去算距离。为什么混都是“距离库长”名字一样。怎么区分反射率和多普勒是两套独立的距离刻度第一个库的实际距离也分别存在 47-48 和 49-50 字节。算速度数据的距离时必须用多普勒那套库长和首库距离混用会让速度图的空间尺度整体拉伸四倍。4.5 把“距离模糊”当成“无回波”易混点编码值 0 是无回波编码值 1 是距离模糊两个都是特殊值有人统一当缺失处理。为什么混都不套公式看起来都“不是正常数据”。怎么区分无回波是真的没信号距离模糊是信号来自更远处、被折叠进来了物理含义完全不同。做质量控制时距离模糊点该单独标记不能和无回波一起抹掉否则会丢掉远处强回波的线索。5. 什么时候该用这份格式说明什么时候别硬套先说该用的场景。如果你手上有一批 CINRAD SA/SB 或 CA/CB 的基数据文件想把它还原成反射率、速度、谱宽的二维或三维场这份格式说明就是必需的对照表——从 28 字节信息头逐字段解析按指针定位三块数据区按编码公式翻译成物理量按库长和首库距离还原空间坐标最后按径向状态位切仰角层。整个链路里每一步都依赖格式里的某个字段缺一环就断。尤其是做历史数据回算、做算法验证、做教学演示这种“从字节到物理量”的完整还原能力是绕不开的基本功。再说别硬套的场景。第一如果你只是要看现成的雷达图产品没必要碰基数据——产品级数据已经做过坐标变换、质量控制、拼图直接拿来用效率高得多硬啃基数据属于用放大镜看报纸费力不讨好。第二不同雷达型号、不同年代的格式可能有细微差异这份说明覆盖的是 SA/SB 和 CA/CB 两类遇到别的型号别想当然套用先确认字段定义是否一致。第三格式里的保留字段比如 1-14、17-28、75-82、91-128 这些不要自作主张去解读保留就是保留里面可能是历史遗留或厂商私有内容硬读出来的东西没有意义还可能误导后续判断。我自己的习惯是每次拿到一批新来源的基数据先不急着写解析逻辑而是先抽一条径向把 28 字节信息头逐字段打印出来核对数据类型标识是不是 1、方位角和仰角算出来是否落在合理范围、三个指针是否指向文件内合法位置、库数和波段是否匹配。这一遍走完心里就有底了后面批量处理才不容易翻车。从那以后我每次读陌生格式的基数据都强制先走一遍这个“单条径向体检”省下的调试时间远比这一步花的多。希望这套思路帮到你。如果你想把这份格式说明连同字段表、编码公式、数组定义一起留着随时对照完整资料已经整理好按文末方式获取即可读基数据的时候摊在手边比来回翻网页踏实。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?