【WRF-Chem工具】pyVPRM_examples 其一 wrf_preprocessor 详解

wrf_preprocessor 详解-目录

GitHub 上的 Python 包 pyVPRM

本博客对 pyVPRM_examples 中 案例1:生成 WRF 模型输入(wrf_preprocessor)进行详细解释,pyVPRM的安装可参考另一博客-【WRF-Chem工具】pyVPRM 计算大气与陆地植被之间的 CO₂ 交换通量

克隆示例仓库:

bash 复制代码
git clone https://github.com/tglauch/pyVPRM_examples.git

示例目录说明:

文件夹 功能
./wrf_preprocessor 生成 WRF 模型输入
./vprm_predictions 生成 GPP / NEE 通量预测
./fit_vprm_parameters 拟合 VPRM 参数
./sat_data_download 下载 MODIS / VIIRS 数据

用于脚本的数据已经预处理过 ,目的是为了节省内存空间(可能是裁剪、下采样、压缩等)。

输入/输出文件概览

外部数据准备

使用以下 3 类主要外部数据:

数据类型 数据来源 格式 用途
1. 卫星遥感数据 MODIS 或 VIIRS .hdf 提取植被指数(EVI、LSWI)、用于 VPRM 输入
2. 土地覆盖地图 Copernicus Land Cover GeoTIFF 或 NetCDF 提供植被类型(森林、农田、草地等)
3. WRF 地理网格文件 WRF 模型(geo_em)输出 .nc (NetCDF) 获取模拟区域的网格经纬度信息,用于裁剪和重投影

区域范围 :聚焦于 亚马逊地区的 ATTO 塔(Amazon Tall Tower Observatory)周围区域

数据来源

  • MODIS 卫星数据:提供遥感植被参数(如 NDVI、EVI、LAI 等)。
  • Copernicus 地表覆盖图(Land Cover Map):提供土地利用/覆盖类型(如森林、草地、农田等)的空间分布信息。

在命令行中运行这个脚本:

bash 复制代码
source activate pyvprm_env
python vprm_preprocessor_new.py --year 2022 --config ./config/preprocessor_config.yaml

需要说明的是,代码需要需要 Github-copernicus_land_cover_wrf.yaml 文件,下载后上传至 $HOME/miniconda3/envs/pyvprm_env/lib/python3.9/site-packages/pyVPRM/vprm_configs/ 文件夹。

运行成功,如下:

生成的文件如下:

输出文件总览

输出文件的可视化可以参考另一博客-【WRF-VPRM 预处理器第五期】基于Python读取并可视化生成的 EVI、LSWI 指数文件

文件名 内容 是否用于 WRF-VPRM 说明
VPRM_input_EVI_2022_part_1_1.nc 主动植被指数(EVI)时间序列 每个时间步对应一个 EVI 图层
VPRM_input_EVI_MAX_2022_part_1_1.nc 年度最大 EVI 用于归一化
VPRM_input_EVI_MIN_2022_part_1_1.nc 年度最小 EVI 用于归一化
VPRM_input_LSWI_2022_part_1_1.nc LSWI 时间序列(湿度相关) 与水分胁迫相关
VPRM_input_LSWI_MAX_2022_part_1_1.nc 年度最大 LSWI 用于计算水分胁迫函数
VPRM_input_LSWI_MIN_2022_part_1_1.nc 年度最小 LSWI 同上
VPRM_input_VEG_FRA_2022_part_1_1.nc 植被覆盖率(vegetation fraction) 类似于 WRF 的 VEGFRA,用于调节 VPRM 通量强度
⚙️ regridder_1_1.nc 重投影转换矩阵(xESMF regridder) 缓存文件,可删除或保留加速重投影
⚙️ regridder_1_1_lcm.nc 土地覆盖图的重投影矩阵 同上,用于 Copernicus 重采样
⚙️ veg_map_on_modis_grid_1_1.nc MODIS 网格上的土地覆盖图 中间产品,可用于检查处理正确性

所有 VPRM 输入文件遵循以下命名格式:

复制代码
VPRM_input_<VAR>_<YEAR>_part_<chunk_x>_<chunk_y>.nc
  • <VAR>:变量名,如 EVI, LSWI, VEG_FRA, EVI_MAX, 等
  • <YEAR>:年份(你运行脚本时指定的 --year 参数)
  • part_<chunk_x>_<chunk_y>:表示 WRF 网格被分块处理的编号(用于大网格并行处理)

代码详解

为 WRF 模型(Weather Research and Forecasting)生成 VPRM 模型的输入数据。

配置文件 config.yaml

preprocessor_config.yaml 内容如下:

bash 复制代码
years:
 - 2022
satellite: modis
sat_image_path: ./data/modis/
copernicus_path: ./data/copernicus/
out_path: ./out/
geo_em_file: ./data/geo_em.d04.nc
n_chunks: 1
hvs:
 - [12,9] 

文件路径通常是相对路径或绝对路径,需确保文件存在,否则脚本会报错或跳过处理。

函数1:vprm_preprocessor_new.py

vprm_preprocessor_new.py 结合卫星遥感数据(MODIS 或 VIIRS)和土地覆盖数据(Copernicus),生成多个 NetCDF 文件供 WRF-VPRM 模型读取。

text 复制代码
           ┌────────────────────┐
           │ 读取命令行参数和配置  │
           └────────┬───────────┘
                    ▼
         ┌──────────────────────┐
         │ 读取WRF网格和MODIS tile │
         └────────┬─────────────┘
                  ▼
    ┌────────────────────────────┐
    │ 读取遥感数据(MODIS/VIIRS) │
    └────────┬───────────────────┘
             ▼
 ┌───────────────────────────────┐
 │ 添加到VPRM实例 + 平滑 + 裁剪     │
 └────────┬──────────────────────┘
          ▼
 ┌───────────────────────────────┐
 │ 加载 Copernicus 地表覆盖图      │
 └────────┬──────────────────────┘
          ▼
 ┌───────────────────────────────┐
 │ 重投影到WRF网格 + 输出NetCDF    │
 └───────────────────────────────┘

一、导入模块

python 复制代码
import os
import pyVPRM
...
  • 基本库os, glob, argparse, time, datetime, numpy, xarray, yaml
  • 遥感处理库pyVPRM(自定义库,核心处理逻辑)、shapely, geopandas, pyproj
  • pyVPRM模块说明
    • sat_managers.modis: 读取 MODIS 数据
    • sat_managers.viirs: 读取 VIIRS 数据
    • sat_managers.copernicus: 读取 Copernicus 地表覆盖图
    • lib.functions: 一些辅助函数,如经纬度转 MODIS tile 等
    • VPRM.vprm_preprocessor: 主处理类,构建 VPRM 输入

二、命令行参数解析

python 复制代码
p = argparse.ArgumentParser(...)
p.add_argument("--config", type=str)
p.add_argument("--year", type=int)
p.add_argument("--n_cpus", type=int, default=1)
p.add_argument("--chunk_x", type=int, default=1)
p.add_argument("--chunk_y", type=int, default=1)
args = p.parse_args()
  • 读取运行参数:
    • --config: YAML 配置文件路径
    • --year: 处理哪一年的数据(如 2022)
    • --n_cpus: 并行使用的 CPU 核心数
    • --chunk_x, --chunk_y: 用于分块处理 WRF 网格(节省内存)

三、读取配置文件 + 创建输出目录

python 复制代码
with open(args.config, "r") as stream:
    cfg  = yaml.safe_load(stream)
  • 读取 YAML 配置,包含:
    • 输入路径(MODIS/VIIRS 数据、Copernicus 数据)
    • 输出路径
    • WRF 地理网格文件路径(geo_em.d0X.nc)

四、读取 WRF 网格并确定 MODIS Tiles

python 复制代码
out_grid = parse_wrf_grid_file(cfg['geo_em_file'], ...)
hvs = np.unique([...lat_lon_to_modis(...)])
  • 使用 WRF geo_em 文件 读取目标模拟区域的网格信息(lat/lon)
  • 利用 lat_lon_to_modis 函数确定该区域覆盖的 MODIS tile 编号(h, v)

五、逐个 MODIS tile 加载数据

python 复制代码
for i in hvs:
    file_collections = glob.glob(...)
    new_inst = vprm_preprocessor(...)
    for fpath in file_collections:
        handler = modis(...) 或 VIIRS(...)
        handler.load()
  • 遍历每个 tile,对应的 .hdf 文件逐个加载(MODIS 或 VIIRS)
  • 每个 tile 创建一个 vprm_preprocessor 实例
  • 加载遥感数据后,裁剪到 WRF 区域(使用 shapely boxcrop_box()

六、添加遥感数据到 VPRM 实例

python 复制代码
new_inst.add_sat_img(...)
  • 添加遥感波段数据:
    • MODIS: b_nir, b_red, b_blue, b_swir
    • VIIRS: 波段命名不同
  • 自动计算 NDVI、EVI、LSWI 等植被指数
  • 可选项:去除云、坏像元、裁剪波段

七、数据处理(时序平滑、裁剪)

python 复制代码
new_inst.sort_and_merge_by_timestamp()
new_inst.lowess(...)
new_inst.clip_values(...)
  • 合并所有影像数据,按时间排序
  • 使用 LOWESS 平滑(局部加权回归)对 EVI 和 LSWI 时间序列进行去噪
  • 限定 evilswi 的取值范围,移除异常值

八、添加土地覆盖图(Copernicus)

python 复制代码
handler_lt = copernicus_land_cover_map(...)
handler_lt.load()
handler_lt.crop_to_polygon(...)
vprm_inst.add_land_cover_map(...)
  • 加载 Copernicus 地图(GeoTIFF 或 NetCDF)
  • 对其裁剪到遥感图像覆盖区域
  • 若土地覆盖图已存在,直接加载;否则重新生成并保存

九、将 VPRM 数据重投影到 WRF 网格

python 复制代码
wrf_op = vprm_inst.to_wrf_output(out_grid, driver='xESMF', ...)
  • 使用 xESMF 进行网格重采样(卫星网格 → WRF 网格)
  • 支持并行处理(但此处未启用 MPI)

十、保存为 NetCDF 文件

python 复制代码
for key in wrf_op.keys():
    wrf_op[key].to_netcdf(...)
  • 输出变量包括:

    • EVI, EVI_MAX, EVI_MIN
    • LSWI, LSWI_MAX, LSWI_MIN
    • VEG_FRA(植被覆盖率)
  • 文件命名格式:

    复制代码
    VPRM_input_<VAR>_<YEAR>_part_<chunk_x>_<chunk_y>.nc

十一、完成提示

python 复制代码
print('Done. In order to inspect the output use evaluate_wrf_input.ipynb')
  • 提示用户使用 notebook 脚本进行可视化检查输出结果。

输出文件可视化

读取 VPRM 植被类别覆盖率

VPRM 类别(共 8 类;Function Types)

VPRM类别编号 类别名称 描述
1 Trees evergreen 常绿树(全年绿色)
2 Trees deciduous 落叶树(季节性掉叶)
3 Trees mixed 混合林(常绿+落叶)
4 Trees and shrubs 树木+灌木混合区
5 Trees and grasses 树木+草地混合
6 Trees and crops 树木+农作物混合
7 Grasses 草地或草原
8 Barren, Urban, Snow, Ice 荒地、城市、雪、冰

绘制的图形如下:

对应 Python 代码如下:

bash 复制代码
import os
import numpy as np
import xarray as xr
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from matplotlib.colors import LinearSegmentedColormap

# 设置字体
plt.rcParams['font.family'] = 'Times New Roman'

# VPRM 类别映射表(class_index 从 0 开始)
vprm_classes = {
    0: "Trees evergreen",
    1: "Trees deciduous",
    2: "Trees mixed",
    3: "Trees and shrubs",
    4: "Trees and grasses",
    5: "Trees and crops",
    6: "Grasses",
    7: "Barren, Urban, Snow, Ice"
}

def get_custom_colormap(class_index):
    """
    根据植被类型返回对应的颜色映射。
    """
    if class_index == 7:
        # 第8类:白 -> 深黄
        return LinearSegmentedColormap.from_list("yellow_map", ["white", "gold", "darkorange"])
    else:
        # 其余类型:白 -> 浅绿 -> 深绿
        return LinearSegmentedColormap.from_list("green_map", ["white", "lightgreen", "darkgreen"])


def plot_variable(
    data,
    var_name,
    lons,
    lats,
    output_path,
    title='',
    lon_range=(65, 100),
    lat_range=(5, 40),
    cmap=None
):
    fig = plt.figure(figsize=(10, 8))
    ax = plt.axes(projection=ccrs.PlateCarree())
    ax.set_extent([*lon_range, *lat_range], crs=ccrs.PlateCarree())

    ax.add_feature(cfeature.COASTLINE, linewidth=0.8)
    ax.add_feature(cfeature.BORDERS, linestyle=':', linewidth=0.6)
    ax.add_feature(cfeature.LAND, edgecolor='black', linewidth=0.3)
    gl = ax.gridlines(draw_labels=True, linewidth=0.5, color='gray', alpha=0.5)
    gl.top_labels = False
    gl.right_labels = False
    gl.xlabel_style = {'size': 13}
    gl.ylabel_style = {'size': 13}

    # 使用 xarray 方式裁剪区域
    data_sub = data.where(
        (data['lon'] >= lon_range[0]) & (data['lon'] <= lon_range[1]) &
        (data['lat'] >= lat_range[0]) & (data['lat'] <= lat_range[1]),
        drop=True
    )

    im = ax.pcolormesh(
        data_sub['lon'],
        data_sub['lat'],
        data_sub,
        cmap=cmap,
        shading='auto',
        vmin=0,
        vmax=1
    )

    cbar = plt.colorbar(im, ax=ax, orientation='vertical', fraction=0.046, pad=0.04)
    cbar.set_label("Fraction", fontsize=15)
    cbar.ax.tick_params(labelsize=13)

    plt.title(title, fontsize=16)
    plt.savefig(output_path, dpi=500, bbox_inches='tight')
    plt.close()
    print(f"✅ Saved: {output_path}")


def plot_all_veg_classes(
    file_path=r"D:\0 DataBase\WRF-VPRM\VPRM_input_VEG_FRA_2020.nc",
    output_dir=r"D:\0 DataBase\WRF-VPRM\Figures",
    lon_range=(65, 100),
    lat_range=(5, 40)
):
    os.makedirs(output_dir, exist_ok=True)

    ds = xr.open_dataset(file_path)
    var_name = [v for v in ds.data_vars if 'fraction' in v][0]
    var = ds[var_name]

    lons = ds['lon'].values
    lats = ds['lat'].values

    for class_index in range(var.shape[0]):
        class_name = vprm_classes.get(class_index, f"Class {class_index + 1}")
        data = var.isel(vprm_classes=class_index)

        title = f"Vegetation Fraction | {class_name}"
        filename = f"{os.path.splitext(os.path.basename(file_path))[0]}_{var_name}_c{class_index}.png"
        output_path = os.path.join(output_dir, filename)

        custom_cmap = get_custom_colormap(class_index)

        plot_variable(
            data=data,
            var_name=var_name,
            lons=lons,
            lats=lats,
            output_path=output_path,
            title=title,
            lon_range=lon_range,
            lat_range=lat_range,
            cmap=custom_cmap
        )


# 执行
if __name__ == "__main__":
    plot_all_veg_classes(
        file_path=r"D:\0 DataBase\VPRM_input_VEG_FRA_2022.nc",
        output_dir=r"D:\0 DataBase\WRF-VPRM\Figures",
        lon_range=(-59.2, -58.7),
        lat_range=(-2.4, -1.9)
    )

读取 VPRM 生成的 EVI、LSWI 指数文件

绘制以下三个变量的空间分布图(EVI / LSWI):

  • EVI, EVI_MAX, EVI_MIN
  • LSWI, LSWI_MAX, LSWI_MIN

每个文件都包含 8 个植被类别(vprm_classes) ,沿维度 vprm_classes

绘制的图形如下:

对应 Python 代码如下:

bash 复制代码
import os
import xarray as xr
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import numpy as np

# ================= 配置区域 =================

# 1. 设置输入输出路径
BASE_DIR = r"D:\0 DataBase\WRF-VPRM"
OUTPUT_DIR = r"D:\0 DataBase\WRF-VPRM\Figures"

# 2. 文件映射 (Key: 标识符, Value: 文件名)
FILE_MAP = {
    "evi": "VPRM_input_EVI_2022_part_1_1.nc",
    "evi_max": "VPRM_input_EVI_MAX_2022_part_1_1.nc",
    "evi_min": "VPRM_input_EVI_MIN_2022_part_1_1.nc",
    "lswi": "VPRM_input_LSWI_2022_part_1_1.nc",
    "lswi_max": "VPRM_input_LSWI_MAX_2022_part_1_1.nc",
    "lswi_min": "VPRM_input_LSWI_MIN_2022_part_1_1.nc",
}

# 3. 类别名称定义 (用于标题)
VPRM_CLASSES = {
    0: "Trees evergreen",
    1: "Trees deciduous",
    2: "Trees mixed",
    3: "Trees and shrubs",
    4: "Trees and grasses",
    5: "Trees and crops",
    6: "Grasses",
    7: "Barren/Urban/Snow"
}

# 4. 绘图设置
# 自定义绘制第几个 frame (对应类别索引 0-7)
TARGET_CLASS_INDEX = 0

# 经纬度范围 (West, East, South, North)
LON_RANGE = (-59.2, -58.7)
LAT_RANGE = (-2.4, -1.9)

# 字体设置
plt.rcParams['font.family'] = 'Times New Roman'


# ================= 功能函数 =================

def get_coord_names(ds):
    """尝试自动获取经纬度坐标的名称"""
    lat_name, lon_name = None, None

    # 常见命名列表
    lat_candidates = ['lat', 'latitude', 'XLAT', 'XLAT_M']
    lon_candidates = ['lon', 'longitude', 'XLONG', 'XLONG_M']

    for lat in lat_candidates:
        if lat in ds.coords or lat in ds.data_vars:
            lat_name = lat
            break

    for lon in lon_candidates:
        if lon in ds.coords or lon in ds.data_vars:
            lon_name = lon
            break

    return lat_name, lon_name


def plot_vprm_variable(file_key, file_name, class_index, lon_range, lat_range):
    file_path = os.path.join(BASE_DIR, file_name)

    if not os.path.exists(file_path):
        print(f"❌ File not found: {file_path}")
        return

    try:
        with xr.open_dataset(file_path) as ds:
            # 1. 动态获取主变量名 (假设文件中除经纬度时间外只有一个主变量)
            # 排除常见的坐标变量名
            exclude_vars = ['Times', 'vprm_classes', 'time', 'lat', 'lon', 'XLAT', 'XLONG']
            data_vars = [v for v in ds.data_vars if v not in exclude_vars]

            if not data_vars:
                # 如果过滤太严格,回退到取第一个变量,或者尝试匹配文件名中的关键字
                # 这里尝试匹配 file_key (如 evi)
                candidates = [v for v in ds.data_vars if file_key.lower() in v.lower()]
                if candidates:
                    var_name = candidates[0]
                else:
                    var_name = list(ds.data_vars)[0]  # 最后的手段
            else:
                var_name = data_vars[0]

            da = ds[var_name]

            # 2. 维度处理 (Time 和 Class)
            # 处理 Time 维度
            if "time" in da.dims:
                da = da.isel(time=0)

            # 处理 Class 维度 (vprm_classes)
            # 注意:有些文件可能维度名叫 'vprm_classes',有些可能是 'z' 或其他,这里主要依赖名称
            if "vprm_classes" in da.dims:
                if class_index >= da.sizes['vprm_classes']:
                    print(
                        f"⚠️ Index {class_index} out of bounds for {file_key}. Max is {da.sizes['vprm_classes'] - 1}.")
                    return
                da = da.isel(vprm_classes=class_index)
            else:
                # 尝试检查是否是第3维 (假设顺序是 time, class, lat, lon 或 class, lat, lon)
                # 如果维度数量 > 2 (lat, lon),且没有显式的 vprm_classes
                if len(da.dims) >= 3 and da.shape[0] == 8:  # 假设8个类别
                    print(f"ℹ️ Implicit class dimension found for {file_key}, selecting index {class_index}")
                    da = da[class_index, :, :]

            # 3. 坐标识别与裁剪
            lat_name, lon_name = get_coord_names(ds)
            if not lat_name or not lon_name:
                print(f"❌ Could not identify lat/lon coordinates in {file_key}")
                return

            # 使用 where 进行裁剪 (比 sel 更通用,因为 WRF 可能是非规则网格)
            # 注意:如果数据很大,这里可能会慢。对于规则网格可以用 .sel(lon=slice(...))
            mask = (
                    (ds[lon_name] >= lon_range[0]) & (ds[lon_name] <= lon_range[1]) &
                    (ds[lat_name] >= lat_range[0]) & (ds[lat_name] <= lat_range[1])
            )

            # 提取数据值和坐标值用于绘图
            # 注意:对于非规则网格,需要保留二维坐标
            da_masked = da.where(mask)

            # 为了绘图范围准确,我们需要裁剪掉全为 NaN 的边缘 (可选,但推荐)
            # 这里简单处理:直接绘图,通过 set_extent 控制视野

            # 4. 绘图
            fig = plt.figure(figsize=(10, 8))
            ax = plt.axes(projection=ccrs.PlateCarree())
            ax.set_extent([lon_range[0], lon_range[1], lat_range[0], lat_range[1]], crs=ccrs.PlateCarree())

            # 添加地图要素
            ax.add_feature(cfeature.COASTLINE, linewidth=0.8)
            ax.add_feature(cfeature.BORDERS, linestyle=':', linewidth=0.6)
            # ax.add_feature(cfeature.LAND, edgecolor='black', linewidth=0.3, facecolor='none') # 可选

            # 网格线
            gl = ax.gridlines(draw_labels=True, linewidth=0.5, color='gray', alpha=0.5, linestyle='--')
            gl.top_labels = False
            gl.right_labels = False
            gl.xlabel_style = {'size': 12, 'family': 'Times New Roman'}
            gl.ylabel_style = {'size': 12, 'family': 'Times New Roman'}

            # 绘制数据
            # 使用 pcolormesh,注意 x 和 y 应该是二维的如果这是 WRF 输出
            im = ax.pcolormesh(
                ds[lon_name], ds[lat_name], da_masked,
                cmap='YlGn',
                shading='auto',
                vmin=0, vmax=1,  # EVI/LSWI 通常在 0-1 之间,可根据需要调整
                transform=ccrs.PlateCarree()
            )

            # 色标
            cbar = plt.colorbar(im, ax=ax, orientation='vertical', fraction=0.046, pad=0.04)
            cbar.set_label(var_name.upper(), fontsize=14)
            cbar.ax.tick_params(labelsize=12)

            # 标题
            class_name = VPRM_CLASSES.get(class_index, f"Class {class_index}")
            title_str = f"{file_key.upper()} | {class_name} (Index: {class_index})"
            plt.title(title_str, fontsize=16, pad=10)

            # 保存
            os.makedirs(OUTPUT_DIR, exist_ok=True)
            save_name = f"{file_key}_class_{class_index}.png"
            save_path = os.path.join(OUTPUT_DIR, save_name)

            plt.savefig(save_path, dpi=300, bbox_inches='tight')
            plt.close()
            print(f"✅ Saved: {save_name}")

    except Exception as e:
        print(f"❌ Error processing {file_key}: {str(e)}")
        import traceback
        traceback.print_exc()


# ================= 主程序 =================

if __name__ == "__main__":
    print(f"Starting plot generation for Class Index: {TARGET_CLASS_INDEX}")
    print(f"Output Directory: {OUTPUT_DIR}")

    for key, filename in FILE_MAP.items():
        plot_vprm_variable(
            file_key=key,
            file_name=filename,
            class_index=TARGET_CLASS_INDEX,
            lon_range=LON_RANGE,
            lat_range=LAT_RANGE
        )

    print("All tasks completed.")

参考

1、GitHub 上的 Python 包 pyVPRM

相关推荐
WangYan20224 个月前
Python气象与海洋:安装入门+科学计算库+可视化+台风数据+WRF/ROMS后处理+EOF分析+机器学习
python·气象·wrf·海洋
WW、forever5 个月前
【WRF-Chem Emissions教程第八期】转换实用程序
wrf·wrf-chem
WW、forever5 个月前
【WRF-Chem第二期】WRF-Chem有关 namelist 详解
wrf·wrf-chem
WW、forever6 个月前
【WRFDA数据教程第一期】LITTLE_R 格式详细介绍
wrf·wrfda
WW、forever6 个月前
常见混沌系统:Lorenz 1963 模型
wrf·wrfda
WW、forever9 个月前
【WRF理论第十七期】单向/双向嵌套机制(含namelist.input详细介绍)
wps·wrf
WW、forever9 个月前
【WRF工具】GIS4WRF详细介绍:配置 WPS/WRF
qgis·wrf
WW、forever1 年前
【WRF教程第3.5期】预处理系统 WPS 详解:以4.5版本为例
wrf
WW、forever1 年前
【WPS安装】WPS编译错误总结:WPS编译失败+仅编译成功ungrib等
wrf