python:nc文件转换为tiff格式(仿射变换)

# nc格式转换tiff
# date: 2021-11-10
# author: Zhangli
import netCDF4 as nc
from osgeo import gdal,osr,ogr
import numpy as np
import os
from netCDF4 import Dataset
import glob
import pandas as pd

# 单个nc数据ndvi数据读取为多个tif文件,并将ndvi值化为-1-1之间
# def NC_to_tiffs(data,Output_folder):
#     nc_data_obj = nc.Dataset(data)
#     Lon = nc_data_obj.variables['lon2d'][:]
#     Lat = nc_data_obj.variables['lat2d'][:]
#     print(Lon)
#     co = np.asarray(nc_data_obj.variables['co']) #将ndvi数据读取为数组
#     # ndvi_arr_float = ndvi_arr.astype(float)/10000 #将int类型改为float类型,并化为-1 - 1之间
#     #影像的左上角和右下角坐标
#     LonMin,LatMax,LonMax,LatMin = [Lon.min(),Lat.max(),Lon.max(),Lat.min()]
#     #分辨率计算
#     N_Lat = len(Lat)
#     N_Lon = len(Lon)
#     Lon_Res = (LonMax - LonMin) /(float(N_Lon)-1)
#     Lat_Res = (LatMax - LatMin) / (float(N_Lat)-1)
#     for i in range(len(co[:])):
#         #创建.tif文件
#         driver = gdal.GetDriverByName('GTiff')
#         out_tif_name = Output_folder + '\\'+ data.split('\\')[-1].split('.')[0] + '_' + str(i+1) + '.tif'
#         out_tif = driver.Create(out_tif_name,N_Lon,N_Lat,1,gdal.GDT_Float32)
#         # 设置影像的显示范围
#         #-Lat_Res一定要是-的
#         geotransform = (LonMin,Lon_Res, 0, LatMax, 0, -Lat_Res)
#         out_tif.SetGeoTransform(geotransform)
#         #获取地理坐标系统信息,用于选取需要的地理坐标系统
#         srs = osr.SpatialReference()
#         srs.ImportFromEPSG(4326) # 定义输出的坐标系为"WGS 84",AUTHORITY["EPSG","4326"]
#         out_tif.SetProjection(srs.ExportToWkt()) # 给新建图层赋予投影信息
#         #数据写出
#         print(co.shape)
#         out_tif.GetRasterBand(1).WriteArray(co[i]) # 将数据写入内存,此时没有写入硬盘 此处[::-1]用于图像的垂直镜像对称,避免图像颠倒
#         out_tif.FlushCache() # 将数据写入硬盘
#         out_tif = None # 注意必须关闭tif文件

def arange_(lower, upper, step, dtype=None):
    npnt = np.floor((upper - lower) / step) + 1
    upper_new = lower + step * (npnt - 1)
    if np.abs((upper - upper_new) - step) < 1e-10:
        upper_new += step
        npnt += 1
    return np.linspace(lower, upper_new, int(npnt), dtype=dtype)

def save_tif(data, savepath, fields_name=[]):
    nc_data_obj = nc.Dataset(data)
    print(nc_data_obj.variables)
    Lon = nc_data_obj.variables['lon2d'][:]
    Lat = nc_data_obj.variables['lat2d'][:]

    LonMin, LatMax, LonMax, LatMin = [Lon.min(), Lat.max(), Lon.max(), Lat.min()]
    # 分辨率计算
    N_Lat = len(Lat)
    N_Lon = len(Lon)
    Lon_Res = (LonMax - LonMin) / (float(N_Lon) - 1)

    Lat_Res = (LatMax - LatMin) / (float(N_Lat) - 1)

    xgrid = arange_(LonMin, LonMax, Lon_Res, dtype=np.float64) + Lon_Res / 2
    ygrid = arange_(LatMin, LatMax, Lat_Res, dtype=np.float64) + Lat_Res / 2

    nrows = len(ygrid)
    ncols = len(ygrid)
    if len(fields_name) == 0:
        print ('no fields_name provided, adding ')
    if len(fields_name) > 1:
        print ('only one field is supported to save as GeoTIFF, usually column_amount. returning')
        return
    try:
        import rasterio
        from rasterio.transform import Affine
    except:
        print ('rasterio not available. returning')
        return
    transform = Affine.translation(xgrid[0] - Lon_Res / 2, ygrid[0] - Lat_Res / 2) \
                * Affine.scale(Lon_Res, Lat_Res)
    with rasterio.open(
            savepath, 'w',
            driver='GTiff',
            height=nrows,
            width=ncols,
            count=1,
            transform=transform,
            crs='+proj=latlong',
            dtype=np.float32,
    ) as dataset:
        arr = np.squeeze(nc_data_obj.variables[fields_name[0]],axis = 0)
        dataset.write(arr, 1)

if __name__ == "__main__":
    data = r'D:\jyyjjjdaqiwuranshujunctotiff\nc\CN-Reanalysis-yearly-2013010100.nc'
    savepath = r'D:\jyyjjjdaqiwuranshujunctotiff\result\2013_co.tif'
    fields_name= ['co']
    save_tif(data, savepath, fields_name)

你可能感兴趣的:(遥感算法,python,数据下载,python,开发语言)