# NavSea Weather Server Task: WeatherServer_GridBuilder Architecture: NavSea V11 Codex: codex6 Status: TODO --- # 1 任务目标 实现 Weather Grid Builder 模块。 功能: 将 GRIB 数据解析为统一的 Weather Grid 数据结构。 输入: data/grib/*.grib2 输出: data/grid/*.json Weather Grid 将作为: Vector Tile Generator Routing Engine Weather Analysis 的基础数据源。 --- # 2 输入数据 GRIB 文件来自 Downloader。 示例: data/grib/ 20260312_00_f000.grib2 20260312_00_f003.grib2 20260312_00_f006.grib2 变量: UGRD VGRD APCP PRMSL TMP --- # 3 Weather Grid 数据结构 每个 grid 点结构: { "lat": float, "lon": float, "wind_speed": float, "wind_dir": float, "rain": float, "temp": float, "pressure": float } 说明: lat 纬度 lon 经度 wind_speed m/s wind_dir 度 rain mm temp 摄氏度 pressure hPa --- # 4 风速计算 使用 U/V 分量计算: wind_speed = sqrt(u² + v²) --- # 5 风向计算 公式: wind_dir = (atan2(u, v) * 180 / π + 360) % 360 结果: 0–360° --- # 6 Grid Builder 输出 文件: data/grid/ 示例: grid_20260312_00_f000.json 结构: { "time": "20260312_00_f000", "points": [...] } --- # 7 创建文件 weather_server/grid/grid_builder.py --- # 8 实现代码 ```python import os import json import numpy as np import xarray as xr INPUT_DIR = "data/grib" OUTPUT_DIR = "data/grid" os.makedirs(OUTPUT_DIR, exist_ok=True) def compute_wind(u, v): speed = np.sqrt(u**2 + v**2) direction = (np.degrees(np.arctan2(u, v)) + 360) % 360 return speed, direction def process_file(path): ds = xr.open_dataset(path, engine="cfgrib") u = ds["u10"].values v = ds["v10"].values rain = ds["tp"].values pressure = ds["msl"].values temp = ds["t2m"].values lat = ds.latitude.values lon = ds.longitude.values wind_speed, wind_dir = compute_wind(u, v) points = [] for i in range(len(lat)): for j in range(len(lon)): point = { "lat": float(lat[i]), "lon": float(lon[j]), "wind_speed": float(wind_speed[i][j]), "wind_dir": float(wind_dir[i][j]), "rain": float(rain[i][j]), "temp": float(temp[i][j]), "pressure": float(pressure[i][j]) } points.append(point) return points def main(): for file in os.listdir(INPUT_DIR): if not file.endswith(".grib2"): continue path = os.path.join(INPUT_DIR, file) print("processing", file) points = process_file(path) output = os.path.join( OUTPUT_DIR, f"grid_{file.replace('.grib2','')}.json" ) data = { "time": file.replace(".grib2",""), "points": points } with open(output, "w") as f: json.dump(data, f) print("saved", output) if __name__ == "__main__": main()