Files
weather/tasks/WeatherServer_GridBuilder_v2.md
OpenAI Codex c957fef15b Initial import
2026-03-17 19:52:51 +08:00

215 lines
3.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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()