首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >NC批量转TIF:解决转换时图像颠倒、镜像问题

NC批量转TIF:解决转换时图像颠倒、镜像问题

作者头像
疯狂学习GIS
发布2025-08-27 14:40:39
发布2025-08-27 14:40:39
26700
代码可运行
举报
文章被收录于专栏:疯狂学习GIS疯狂学习GIS
运行总次数:0
代码可运行

  本文介绍基于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库符合要求了。

  本文所用代码如下。

代码语言:javascript
代码运行次数:0
运行
复制
import os
import numpy as np
import netCDF4 as nc
from osgeo import gdal
from osgeo import osr

nc_folder = R"e:\LTDR\N07"
tif_folder = R"d:\99_Temp\NDVI\SPEI\TIFF"
data_name = "spei"
nodata = -9999
scale = 10000
res = 0.25

ifnot 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 = res
            lon_res = res
            lat_origin = lat_max + lat_res / 2
            lon_origin = lon_min - lon_res / 2

            for 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.T

                output_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进行左右变换。

  执行上述代码,即可看到转换后的数据在空间方位方面已经没有问题了,如下图所示。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-08-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 疯狂学习GIS 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档