当前位置: 首页 > news >正文

批量将NC格式数据转换为TIF格式:解决转换后图像颠倒、镜像、翻转等问题

  本文介绍基于PythonGDAL模块,批量将大量.nc格式的栅格文件转换为.tif格式,并解决可能出现的转换后图像颠倒、镜像、翻转等问题。

  最近,需要批量将大量.nc格式的栅格文件转换为.tif格式。如下图所示,有多个待转换的.nc格式文件,且对于每一个.nc格式文件,其都含有多个时相的数据。

  其实,对于.nc格式转.tif格式,除了gdal库之外,还有其他非常多成熟、方便的Python库或R语言库可以实现,且这些库都比gdal库用起来方便——甚至安装过程也比gdal库方便;但是,我在一开始用这些其他库进行格式转换时发现:对于我的.nc格式数据,若用其他库进行转换,最终得到的.tif图像并不是正确的——其要么是行列数(也就是经纬度)都反了,要么是经度或纬度其中一个是反着的;包括PythonnetCDF4库、xarray库、rioxarray库,以及R语言的ncdf库等,都存在这个问题。

  如下图所示,这个就是我遇到的其中一种情况。可以看到,这个结果数据的经度倒是没错,但是纬度搞反了,所以全球的图像是反着来的,南极跑到北极去了。

  针对这种情况,我大致看了一下原本的.nc格式数据,感觉问题应该就是出在.nc数据上——比如可能对于一些学者自行生产的科学数据产品,其在数据生产完毕、封装为.nc格式时,经纬度是反着写的;而上述提及的那些成熟的.nc格式转.tif格式的库,他们默认是正着解析经度和纬度的,所以出现了上述问题。

  所以,为了解决这个问题,那就不太好用这些封装好的.nc格式转.tif格式库了,而是需要将.nc格式数据直接提取为类似于array格式的矩阵数据,然后手动进行矩阵变换,再将其导出为.tif——那这样的话,就只有gdal库符合要求了。

  本文所用代码如下。

import os
import numpy as np
import netCDF4 as nc
from osgeo import gdal
from osgeo import osrnc_folder = R"e:\LTDR\N07"
tif_folder = R"d:\99_Temp\NDVI\SPEI\TIFF"
data_name = "spei"
nodata = -9999
scale = 10000
res = 0.25if not os.path.exists(tif_folder):os.makedirs(tif_folder)driver = gdal.GetDriverByName('GTiff')for nc_file in os.listdir(nc_folder):if nc_file.endswith(".nc"):nc_file_path = os.path.join(nc_folder, nc_file)year = nc_file.split("_")[2]with nc.Dataset(nc_file_path) as file:data = np.array(file[data_name][:])times = np.array(file['time'][:])lats = np.array(file['lat'][:])lons = np.array(file['lon'][:])lat_min, lat_max = lats.min(), lats.max()lon_min, lon_max = lons.min(), lons.max()lat_num = len(lats)lon_num = len(lons)lat_res = reslon_res = reslat_origin = lat_max + lat_res / 2lon_origin = lon_min - lon_res / 2for time in range(len(times)):daily_data = data[time, :, :]# scale the data if necessary# daily_data = np.round(data[time, :, :] * scale).astype(np.int32)# Flip the data to match the expected orientation, here are three options:daily_data = np.flipud(daily_data.T)daily_data = np.flipud(daily_data)daily_data = daily_data.Toutput_tif_path = os.path.join(tif_folder,f"SPEI_{year}{str(time + 1).zfill(3)}.tif")outRaster = driver.Create(output_tif_path, lon_num, lat_num, 1, gdal.GDT_Float32)# outRaster = driver.Create(output_tif_path, lon_num, lat_num, 1, gdal.GDT_Int32)outRaster.SetGeoTransform([lon_origin, lon_res, 0, lat_origin, 0, -lat_res])sr = osr.SpatialReference()sr.SetWellKnownGeogCS('WGS84')outRaster.SetProjection(sr.ExportToWkt())band = outRaster.GetRasterBand(1)band.SetNoDataValue(nodata)# scale the data if necessary# band.SetNoDataValue(nodata * scale)band.WriteArray(daily_data)print(output_tif_path, ' finished')del outRaster

  其中,nc_folder就是.nc格式文件所在目录,tif_folder是输出.tif格式文件的目录,data_name是要提取的变量名,nodata表示填充值,scale是缩放系数(例如假设原本的.nc格式文件是浮点数,乘以10000并取整后,存为整数可节省空间),res则是空间分辨率。

  代码整体思路也很简单,主要就是需要关注daily_data = np.flipud(daily_data.T)这句代码以及其下方的2行代码。这里就是将原本.nc格式文件数据加以变换的地方,这里列出了3种变换方法,分别为先转置、后上下颠倒,以及直接上下颠倒,还有直接转置。这里之所以列出3种方法,是因为我当时要转换的.nc格式数据产品有很多种,为了方便就将不同种对我有效果的变换方法都写上了;大家使用代码时,需要注意选择自己适合的变换方法。还有一种情况,就是可能图像还会出现左右颠倒的问题,也就是纬度没问题、但经度反了——不过这种情况感觉一般不会遇到,所以当时就没写变换的代码;如果大家遇到了,那就需要额外对array进行左右变换。

  至此,大功告成。

欢迎关注:疯狂学习GIS

http://www.dtcms.com/a/322166.html

相关文章:

  • 深度剖析主流AI大模型的编程语言与架构选择:行业实践与技术细节解读
  • Uipath Studio中爬取网页信息
  • 安装CST时,报错问题处理
  • 几个概率分布在机器学习应用示例
  • Java-反射
  • C++编程之旅-- -- --类与对象的奇幻征途之初识篇(一)(了解类的基本用法,计算类大小,分析this指针)
  • 【完整源码+数据集+部署教程】海洋物体实例分割系统源码和数据集:改进yolo11-EfficientHead
  • Java【问题 07】SSH不同版本使用jsch问题处理(7.4升级9.7及欧拉原生8.8)
  • WD5202 非隔离降压转换芯片,220V降5V,输出电流80MA
  • Java学习Collection单列集合中的三种通用遍历方法
  • 【Erdas实验教程】029:遥感图像光谱增强(缨帽变换)
  • 经济学从业者职业发展认证体系分析
  • 在 Git 中,将本地分支的修改提交到主分支
  • 数据结构--哈希表与排序、选择算法
  • PVE 9.0 保姆级安装及优化教程(换源、网络配置、远程唤醒等)【基础篇】
  • 农行鉴权问题
  • 嵌入式 Linux 驱动开发常见问题排查宝典(驱动开发篇)v1.0
  • “人工”智能究竟需要多少人工?
  • 《设计模式之禅》笔记摘录 - 14.组合模式
  • 使用Python+selenium实现第一个自动化测试脚本
  • 【GPT-OSS 全面测评】释放推理、部署和自主掌控的 AI 新纪元
  • 1688 图片搜图找货接口开发实战:从图像特征提取到商品匹配全流程
  • InfluxDB漏洞:Metrics 未授权访问漏洞
  • 自定义上传本地文件夹到七牛云
  • 【深度学习新浪潮】GPT-5正式发布:开启博士级智能新纪元
  • Redis基础数据类型
  • 支持向量机(SVM)全解析:原理、类别与实践
  • Nestjs框架: 基于 Argon2 的用户登录注册安全机制设计与实现
  • Vue框架总结案例
  • 抖音AI分身:帮助每个抖音创作者,打造自己的AI分身