# NavSea Weather Server Task: WeatherServer_GridBuilder_v2 Architecture: NavSea V11 Codex: codex6 Status: TODO --- # 1 任务目标 升级 Grid Builder: grid_builder.py → GridBuilder v2 目标: 1 裁剪日本区域 grid 2 使用数组结构保存 grid 3 大幅减少 JSON 文件大小 --- # 2 当前问题 旧版 GridBuilder: 生成全球 grid: 1440 × 721 ≈ 1,038,240 points JSON 文件: ≈ 215MB 这是不可接受的。 Downloader 已经只下载: 120E – 150E 20N – 50N GridBuilder 必须只输出这个区域。 --- # 3 区域范围 REGION: lon_min = 120 lon_max = 150 lat_min = 20 lat_max = 50 理论 grid: (150-120)/0.25 = 120 (50-20)/0.25 = 120 ≈ 14400 grid points --- # 4 新 Grid 数据结构 旧结构: points list { "points":[ {lat,lon,...} ] } 新结构: grid arrays { "time": "...", "lat": [...], "lon": [...], "wind_speed": [...], "wind_dir": [...], "rain": [...], "temp": [...], "pressure": [...] } 优点: 1 文件更小 2 读取更快 3 tile generator 更容易 --- # 5 创建文件 weather_server/grid/grid_builder_v2.py --- # 6 实现代码 ```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) REGION = { "lon_min":120, "lon_max":150, "lat_min":20, "lat_max":50 } 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) lat_idx = np.where( (lat >= REGION["lat_min"]) & (lat <= REGION["lat_max"]) )[0] lon_idx = np.where( (lon >= REGION["lon_min"]) & (lon <= REGION["lon_max"]) )[0] lat_region = lat[lat_idx] lon_region = lon[lon_idx] wind_speed = wind_speed[np.ix_(lat_idx, lon_idx)] wind_dir = wind_dir[np.ix_(lat_idx, lon_idx)] rain = rain[np.ix_(lat_idx, lon_idx)] temp = temp[np.ix_(lat_idx, lon_idx)] pressure = pressure[np.ix_(lat_idx, lon_idx)] return { "lat": lat_region.tolist(), "lon": lon_region.tolist(), "wind_speed": wind_speed.tolist(), "wind_dir": wind_dir.tolist(), "rain": rain.tolist(), "temp": temp.tolist(), "pressure": pressure.tolist() } 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) grid = process_file(path) output = os.path.join( OUTPUT_DIR, f"grid_{file.replace('.grib2','')}.json" ) data = { "time": file.replace(".grib2",""), "grid": grid } with open(output, "w") as f: json.dump(data, f) print("saved", output) if __name__ == "__main__": main()