Convert NC files to GeoTiff format through Python

Convert NC files to GeoTiff format through Python

I. Introduction

  • Based on Python and GDAL library to introduce the basic operations of processing nc files
  • Python function for simply processing nc files into GeoTiff files

2. Basic understanding

  • What is NC format

    NC file is NetCDF ( Network Common Data Form ), which is a common data storage format. It is widely used to store a series of multi-dimensional data such as geosciences, atmospheric sciences, ocean sciences, etc. It can encapsulate data of multiple dimensions such as time, longitude, latitude, precipitation, temperature, etc. The data structure is clear and easy to read, and it can be easily extracted and applied.


  • What is GeoTiff format

    GeoTIFF is a geographic raster file, which can be understood as a Tiff image file format for storing geographic information. Elements such as geographic coordinate system and map projection are directly embedded in the image file.


  • Python libraries needed to process nc files

    • NetCDF4 is used to read NC files; numpy is used to modify data; osgeo's sub-libraries gdal and osr , the former is used to implement conversion and raster editing functions, and the latter can be used to determine geographic coordinate systems and map projections.

      import numpy as np
      import netCDF4 as nc
      from osgeo import gdal,osr
      
    • It is recommended to use Anaconda to configure the virtual Python environment for easy package management. The environment version I use here is

      python 3.6.12(64bit)
      numpy 1.19.1
      netCDF4 1.4.2
      gdal 3.0.2
      

Three, function realization

  1. View NC file information

    import netCDF4 as nc 
    import numpy as np
    
    item = r'***.nc'#选取一个nc文件路径
    DS = nc.Dataset(item)
    
    print(DS,type(NC_DS)) # 返回DS的数据类型,<class 'netCDF4._netCDF4.Dataset'>
    print('{:-<100}'.format('----'))
    
    print(DS.variables) # 了解变量的基本信息
    print('{:-<100}'.format('----'))
    
    print(DS.variables['lon']) # 了解某一变量如“lon”(经度)的基本信息
    print('{:-<100}'.format('----'))
    
    TEMP = NC_DS.variables['temp'][666,123,:] # 这是一个三维数据的NC文件,["纬度","经度","温度"],需要按实际修改
    print(TEMP) # 查看特定维度数据
    

  1. Convert NC files to GeoTiff

    #NetCDF文件处理 
    def Convert(item,day):        
        DS = nc.Dataset(item)
        Lat = DS.variables['lat'][:]
        Lon = DS.variables['lon'][:]
        PREC = DS.variables['prec'][day,:,:] #[day,lon,lat],即生成 某天 全纬度、经度范围 图像
    
        PREC = np.asarray(PREC) #数据类型转换
        PREC[np.where(PREC == -33321)] = np.nan #异常值处理
    
        #影像的部分信息
        LonMin,LatMax,LonMax,LatMin = [Lon.min(),Lat.max(),Lon.max(),Lat.min()] 
    
        #构建tiff框架
        prec_ds = gdal.GetDriverByName('Gtiff').Create(OutTif,len(Lon),len(Lat),1,gdal.GDT_Float32) 
        #dst_ds = driver.Create(dst_filename, xsize, ysize,bands, eType=gdal.GDT_Byte)
        
        #设置影像的显示范围
        prec_ds.SetGeoTransform(LonMin,0.1, 0, LatMin, 0, 0.1)
        #SetGeoTransform(double xLeft,double dX,double 	yProjOnX,double yTop,double x,ProjOnY,double dY)
        #这里通常选取的是左上角点的坐标(lonmin,latmax),但如此我的图像会上下颠倒,不知为何
        #图像分辨率xsize ysize通常在NC属性中给出,也可以 xsize = (lonmax-lonmin)/len(lon)
    
    
        #设置地理坐标系和投影坐标系,这里设置为WGS_84,索引号4326
        srs = osr.SpatialReference()# 获取地理坐标系统信息,用于选取需要的地理坐标系统
        print(type(srs))
        print(srs)
        srs.ImportFromEPSG(4326) # 定义输出的坐标系为"WGS 84",AUTHORITY["EPSG","4326"]
        prec_ds.SetProjection(srs.ExportToWkt()) # 给新建图层赋予投影信息
    
    
        # 数据写出
        prec_ds.GetRasterBand(1).SetNoDataValue(-9999)
        prec_ds.GetRasterBand(1).WriteArray(PREC) # 将数据写入内存
        prec_ds.GetRasterBand(1).GetStatistics(0,1)# 添加统计信息
        prec_ds.FlushCache() # 将数据写入硬盘
        prec_ds = None # 关闭
    

  1. Set up custom projection

        #设置地理坐标系和投影坐标系,这里设置为WGS_84_Albers
        sr = osr.SpatialReference() #获取地理坐标系统信息,用于选取需要的地理坐标系统
        print(type(sr))
        print(sr)
        sr.SetProjCS('WGS_84_Albers')
        sr.SetWellKnownGeogCS('WGS84')#设置地理坐标系为WGS_84
        sr.SetLCC(35,50,0,90,0,0)#设置等面积圆锥投影的参数
        wkt = sr.ExportToWkt()
        #print(wkt)
        sr.ImportFromWkt(wkt) # 将定义好的参数导出为WKT 
        prec_ds.SetProjection(sr.ExportToWkt()) # 给新建图层赋予投影信息 
    

  1. Cut with mask

    from osgeo import gdal
    import os
    import time
    
    def clip(input_shape,input_raster,output_raster):
        
        # 栅格文件路径,打开栅格文件
        input_raster=gdal.Open(input_raster)
            
        # 裁剪,gdal.warp函数,input_shape是掩膜文件
        ds = gdal.Warp(output_raster,input_raster,
            format = 'GTiff',
            cutlineDSName = input_shape, 
            dstNodata = -9999)#设置nodata值为-9999,ArcGIS自动识别为nodata
        
        # 添加统计信息     
        ds.GetRasterBand(1).GetStatistics(0,1)     
        
        # 关闭文件
        ds = None 
    

Fourth, the finished picture preview

  1. Tiff image generated

  1. ArcGIS open properties
    Attributes

  1. Mask cut into imageCrop

Five, reference

  1. Realize nc format to geotiff format based on Python+GDAL .
  2. Use python's netCDF4 library to read .nc files and create .nc files .
  3. Python3.GDAL generates mask from shp file .

Six, summary

本文包括了NC文件读取,NC文件转TIFF、TIFF文件掩膜裁剪、自定投影操作。吸收了多篇文章内容整合而成。代码多有错误,烦请指正。

Guess you like

Origin blog.csdn.net/Taplus/article/details/110674228