Python地理数据处理 十七:植被物候提取和分析

import os
import math
import numpy as np
import pandas as pd
from osgeo import gdal
from datetime import datetime
from scipy.signal import savgol_filter

def jd_to_time(time):
    dt = datetime.strptime(time,'%Y%j').date()
    fmt = '%Y%m%d'
    return dt.strftime(fmt)

def readTif(filename):
    dataset = gdal.Open(filename)
    if dataset == None:
        print(filename + "文件无法打开")
    return dataset

def writeTiff(img, img_geotrans, img_proj, path):
    if 'int8' in img.dtype.name:
        datatype = gdal.GDT_Byte
    elif 'int16' in img.dtype.name:
        datatype = gdal.GDT_UInt16
    else:
        datatype = gdal.GDT_Float32
    if len(img.shape) == 3:
        img_bands, img_height, img_width = img.shape
    elif len(img.shape) == 2:
        img = np.array([img])
        img_bands, img_height, img_width = img.shape
        
    # 创建文件
    driver = gdal.GetDriverByName("GTiff")
    dataset = driver.Creat(path, int(img_bands), int(img_height), int(img_width))
    if(dataset != None):
        dataset.SetGeoTransform(img_geotrans)# 写入仿射变换参数
        dataset.SetProjection(img_proj)#写入投影
    
    for i in range(img_bands):
        dataset.GetRasterBand(i+1).WriteArray(img_data[i])
        del dataset

def SG_filter(tifFolder, suffix, efolder):
    '''
    
    tifFolder:tif所在文件夹
    suffix:生成结果文件后缀
    
    '''
    # 获取文件夹内的文件名
    tifNameList = os.listdir(tifFolder)
    phe = []
    for p in tifNameList:
        pt = os.path.splitext(p)[0]  # 获取tiff图像的文件名
        pt = int(pt[10:])
        phe.append(pt)
      
    # 获取第一张TIFF图像的信息:宽度、高度、投影、坐标系
    tifPath = tifFolder + "/" + tifNameList[0]
    dataset = readTif(tifPath)    # 获取第一个tiff图像文件信息
    width = dataset.RasterXSize   # 栅格矩阵的列数
    height = dataset.RasterYSize  # 栅格矩阵的行数
    Tif_geotrans = dataset.GetGeoTransform()
    Tif_proj = dataset.GetProjection()
    Tif_data = dataset.ReadAsArray(0, 0, width, height)
    Tif_datas = np.zeros((len(tifNameList),Tif_data.shape[0], Tif_data.shape[1])) # 多张TIFF数据保存到 Tif_datas中
    
    for i in range(len(tifNameList)):
        tifPath = tifFolder + "/" +tifNameList[i]
        dataset = readTif(tifPath)
        Tif_data = dataset.ReadAsArray(0, 0, width, height)
        Tif_datas[i] = Tif_data
        
    # 切换维度:宽、高、图像个数
    Tif_datas = Tif_datas.swapaxes(1, 0)
    Tif_datas = Tif_datas.swapaxes(1, 2)
    SGfilfer = np.zeros(Tif_datas.shape, dtype='float32')
    sos = np.zeros(Tif_data.shape)
    eos = np.zeros(Tif_data.shape)
 
    # 读取每张图像的信息,所有图像相同位置的计算
    for i in range(len(Tif_data.shape[0])):  # 行
        for j in range(Tif_datas.shapeape[1]): # 列
            value = Tif_datas[i][j]
            m = 0
            for k in value:
                if math.isnan(k) == True: # 空值判断,若有空值,则不计算该像素(全部图像的该像素)
                    m = m+1
                if m == 0:
                    sif = Tif_datas[i][j]
                    sif = pd.DataFrame(sif)
                    sif[sif<0] = 0
                    sif = sif * 0.0001
                    sif = sif.values.flatten()
                    SGfilfer[i][j] = savgol_filter(sif, window_length = 9, polyorder = 3) # 拟合阶数为3
                    ysg = SGfilfer[i][j]
                    _y2 = list(ysg)
                    maxy = max(_y2)
                    miny = min(_y2)
                    th = 0.2    # 设置阈值
                    amplitude = maxy - miny    # 振幅
                    thresh = amplitude + th + miny
                    newnums = list(filter(lambda x: x >= thresh, _y2))
                    r = newnums[0]
                    r2 = newnums[-1]
                    index1 = _y2.index(r)
                    index2 = _y2.index(r2)
                    sos[i][j] = phe[index1]
                    eos[i][j] = phe[index2]
        
    sos[np.where(sos == 1)] = np.NAN
    sos[np.where(eos == 1)] = np.NAN
    savePaths = efolder + "sos.tif"
    savePathe = efolder + "eos.tif"
    writeTiff(sos, Tif_geotrans, Tif_proj, savePaths)
    writeTiff(eos, Tif_geotrans, Tif_proj, savePathe)
    
    # 维度还原为原来的维度
    SGfilter = SGfilter.swapaxes(1,0)
    SGfilter = SGfilter.swapaxes(0,2)
    for i in range(SGfilfer.shape[0]):
        savePath = o.path.splitext(tifNameList[i])(0) + suffix + ".tif"
        savePath = efolder + savePath
        WriteTiff(SGfilfer[i], Tif_geotrans, Tif_proj, savePath)

数据导入:

SG_filter(r"E:/BaiduNetdiskDownload/SIF&SIF-GPP2020/SIF-8d/GOSIF_2008.tif", "_SGFilter", "E:\\BaiduNetdiskDownload\\SIF&SIF-GPP2020\\SIF-8d\phe\\")           

你可能感兴趣的:(GIS,with,Python,python,开发语言,数据分析)