前言气象数据常常用表格栅格和NC等形式存储由于作者对于nc的处理比较熟悉所以通常是将非nc的形式转成nc或者numpy数组进行处理。一、TIF数据是什么特性GeoTIFF(.tif)NetCDF(.nc)维度仅二维lat/lon单张空间切片支持多维time/lat/lon可存多年逐日数据在一个文件时间存储一个文件 一天靠文件名标记日期内置time坐标变量自带日历信息适用场景遥感、单时次栅格快照气候模式、多时序长序列分析xarray/CDO/NCO 专用配套文件常带.tfw坐标文件自包含不需要额外辅助文件二、使用步骤代码如下示例#!/bin/bash cd /Data/Datasets/CDAT mkdir -p nc concat # 固定绝对输出目录避免相对路径权限异常 CONCAT_DIR/Data/Datasets/CDAT/concat # 第一步tif批量转nc筛选19801201~20051231 for tif in *.tif; do dt$(echo $tif | cut -d_ -f1) if [[ $dt -ge 19801201 $dt -le 20051231 ]]; then bn${tif%.tif} echo 转换 $tif - nc/${bn}.nc gdal_translate \ -of NetCDF \ -co COMPRESSDEFLATE \ -co FORMATNC4 \ -co WRITE_LONLATYES \ $tif ./nc/${bn}.nc fi done #添加时间属性 #!/bin/bash BASE_DIR/Data/Datasets/CDAT NC_DIR${BASE_DIR}/nc cd ${NC_DIR} # 批量给所有nc补充time维度、重命名变量 for nc_file in *.nc; do # 提取文件名日期 YYYYMMDD 纯数字 dt$(echo $nc_file | cut -d_ -f1) echo 处理文件$nc_file 原始日期$dt # 判断变量名 if [[ $nc_file *_avg.nc ]]; then var_nametas_avg elif [[ $nc_file *_min.nc ]]; then var_nametasmin elif [[ $nc_file *_max.nc ]]; then var_nametasmax else echo 文件后缀不匹配跳过 $nc_file continue fi tmp_out${nc_file}.tmp # 直接传入8位纯数字日期不带横杠 cdo settime,$dt $nc_file $tmp_out if [ $? -ne 0 ]; then echo ❌ settime失败跳过 $nc_file rm -f $tmp_out continue fi # 重命名 Band1 为目标气候变量 cdo chname,Band1,$var_name $tmp_out ${tmp_out}.2 if [ $? -ne 0 ]; then echo ❌ 变量重命名失败跳过 $nc_file rm -f $tmp_out ${tmp_out}.2 continue fi # 【修复】mv -f 强制覆盖无交互询问 mv -f ${tmp_out}.2 $nc_file rm -f $tmp_out echo ✅ $nc_file 处理完成time维度变量更名 done echo 全部nc文件time维度补全完毕可执行cdo mergetime合并 #!/bin/bash # 仅执行nc时间拼接tif转换已完成分开处理_avg/_min/_max BASE_DIR/Data/Datasets/CDAT NC_DIR${BASE_DIR}/nc CONCAT_DIR${BASE_DIR}/concat BATCH_SIZE500 # 自动创建输出目录并赋予当前用户读写权限 mkdir -p ${CONCAT_DIR} chmod urwx ${CONCAT_DIR} # 通用分批合并函数 batch_merge(){ local suffix$1 local outfile$2 # 切换至nc目录操作避免路径匹配失效 pushd ${NC_DIR} /dev/null # 空glob不生成*_xxx.nc字面字符串 shopt -s nullglob local nc_list($(ls *${suffix}.nc | sort)) shopt -u nullglob local total_num${#nc_list[]} if [[ ${total_num} -eq 0 ]]; then echo echo 警告无 *${suffix}.nc 文件跳过${suffix#_}合并 echo popd /dev/null return fi echo echo 开始合并 ${total_num} 个 ${suffix} 文件 local tmp_dir./tmp_${suffix} rm -rf ${tmp_dir} mkdir -p ${tmp_dir} # 分批生成临时nc local idx0 while [[ $idx -lt $total_num ]]; do batch_arr(${nc_list[]:$idx:$BATCH_SIZE}) cdo mergetime ${batch_arr[]} ${tmp_dir}/batch_${idx}.nc idx$((idx BATCH_SIZE)) done # 全部临时文件合并为最终成品 local final_out${CONCAT_DIR}/${outfile} [[ -f ${final_out} ]] rm -f ${final_out} cdo mergetime ${tmp_dir}/batch_*.nc ${final_out} # 清理临时文件 rm -rf ${tmp_dir} popd /dev/null echo ✅ ${outfile} 合并完成输出路径${final_out} echo echo } # 依次执行三组独立合并 batch_merge _avg CDAT_avg_198012_200512_concat.nc batch_merge _min CDAT_min_198012_200512_concat.nc batch_merge _max CDAT_max_198012_200512_concat.nc echo 全部合并任务执行完毕 ls -lh ${CONCAT_DIR}/结果处理之后可以用panoply等直接查看生成后的nc文件
利用GDAL转换TIF为nc
发布时间:2026/7/16 8:50:52
前言气象数据常常用表格栅格和NC等形式存储由于作者对于nc的处理比较熟悉所以通常是将非nc的形式转成nc或者numpy数组进行处理。一、TIF数据是什么特性GeoTIFF(.tif)NetCDF(.nc)维度仅二维lat/lon单张空间切片支持多维time/lat/lon可存多年逐日数据在一个文件时间存储一个文件 一天靠文件名标记日期内置time坐标变量自带日历信息适用场景遥感、单时次栅格快照气候模式、多时序长序列分析xarray/CDO/NCO 专用配套文件常带.tfw坐标文件自包含不需要额外辅助文件二、使用步骤代码如下示例#!/bin/bash cd /Data/Datasets/CDAT mkdir -p nc concat # 固定绝对输出目录避免相对路径权限异常 CONCAT_DIR/Data/Datasets/CDAT/concat # 第一步tif批量转nc筛选19801201~20051231 for tif in *.tif; do dt$(echo $tif | cut -d_ -f1) if [[ $dt -ge 19801201 $dt -le 20051231 ]]; then bn${tif%.tif} echo 转换 $tif - nc/${bn}.nc gdal_translate \ -of NetCDF \ -co COMPRESSDEFLATE \ -co FORMATNC4 \ -co WRITE_LONLATYES \ $tif ./nc/${bn}.nc fi done #添加时间属性 #!/bin/bash BASE_DIR/Data/Datasets/CDAT NC_DIR${BASE_DIR}/nc cd ${NC_DIR} # 批量给所有nc补充time维度、重命名变量 for nc_file in *.nc; do # 提取文件名日期 YYYYMMDD 纯数字 dt$(echo $nc_file | cut -d_ -f1) echo 处理文件$nc_file 原始日期$dt # 判断变量名 if [[ $nc_file *_avg.nc ]]; then var_nametas_avg elif [[ $nc_file *_min.nc ]]; then var_nametasmin elif [[ $nc_file *_max.nc ]]; then var_nametasmax else echo 文件后缀不匹配跳过 $nc_file continue fi tmp_out${nc_file}.tmp # 直接传入8位纯数字日期不带横杠 cdo settime,$dt $nc_file $tmp_out if [ $? -ne 0 ]; then echo ❌ settime失败跳过 $nc_file rm -f $tmp_out continue fi # 重命名 Band1 为目标气候变量 cdo chname,Band1,$var_name $tmp_out ${tmp_out}.2 if [ $? -ne 0 ]; then echo ❌ 变量重命名失败跳过 $nc_file rm -f $tmp_out ${tmp_out}.2 continue fi # 【修复】mv -f 强制覆盖无交互询问 mv -f ${tmp_out}.2 $nc_file rm -f $tmp_out echo ✅ $nc_file 处理完成time维度变量更名 done echo 全部nc文件time维度补全完毕可执行cdo mergetime合并 #!/bin/bash # 仅执行nc时间拼接tif转换已完成分开处理_avg/_min/_max BASE_DIR/Data/Datasets/CDAT NC_DIR${BASE_DIR}/nc CONCAT_DIR${BASE_DIR}/concat BATCH_SIZE500 # 自动创建输出目录并赋予当前用户读写权限 mkdir -p ${CONCAT_DIR} chmod urwx ${CONCAT_DIR} # 通用分批合并函数 batch_merge(){ local suffix$1 local outfile$2 # 切换至nc目录操作避免路径匹配失效 pushd ${NC_DIR} /dev/null # 空glob不生成*_xxx.nc字面字符串 shopt -s nullglob local nc_list($(ls *${suffix}.nc | sort)) shopt -u nullglob local total_num${#nc_list[]} if [[ ${total_num} -eq 0 ]]; then echo echo 警告无 *${suffix}.nc 文件跳过${suffix#_}合并 echo popd /dev/null return fi echo echo 开始合并 ${total_num} 个 ${suffix} 文件 local tmp_dir./tmp_${suffix} rm -rf ${tmp_dir} mkdir -p ${tmp_dir} # 分批生成临时nc local idx0 while [[ $idx -lt $total_num ]]; do batch_arr(${nc_list[]:$idx:$BATCH_SIZE}) cdo mergetime ${batch_arr[]} ${tmp_dir}/batch_${idx}.nc idx$((idx BATCH_SIZE)) done # 全部临时文件合并为最终成品 local final_out${CONCAT_DIR}/${outfile} [[ -f ${final_out} ]] rm -f ${final_out} cdo mergetime ${tmp_dir}/batch_*.nc ${final_out} # 清理临时文件 rm -rf ${tmp_dir} popd /dev/null echo ✅ ${outfile} 合并完成输出路径${final_out} echo echo } # 依次执行三组独立合并 batch_merge _avg CDAT_avg_198012_200512_concat.nc batch_merge _min CDAT_min_198012_200512_concat.nc batch_merge _max CDAT_max_198012_200512_concat.nc echo 全部合并任务执行完毕 ls -lh ${CONCAT_DIR}/结果处理之后可以用panoply等直接查看生成后的nc文件