python+gdal GTiff格式的數據類型(datatype)及數據組織(BIP)轉換

GTiff格式文件:
A.修改數據類型(單字節,雙字節,浮點型等)
B.BIP,BIL,BSQ數據組織格式轉換

關鍵函數

Translate(destName, srcDS, **kwargs)

destName — Output dataset name
srcDS — a Dataset object or a filename
options — return of gdal.InfoOptions(), string or array of strings

這裏寫圖片描述

# -*- coding: utf-8 -*-
"""
/***************************************************************************
Translate.py:
    A:數據類型轉換(單字節、雙字節、浮點等)
    讀取配置文件,獲取對應的數據類型
     gdal.Translate(newfilename,self.fileName,outputType=list2[list1.index(parameter)])

    B: BIP、BIL、BSQ格式相互轉換
    GTiff格式數據中,設置INTERLEAVE=BAND or PIXEL ;只能設置BSQ和BIP
    ENVI格式的數據集,可設置數據組織類型,INTERLEAVE爲"BIL,BIP,BSQ"

 @version <1.1> 2018-04-13 Wujd : Created.
***************************************************************************/
"""
from  osgeo import  gdal

class ChangeOrganization:
    def __init__(self, infilename):
        """
        初始化變量
        :param infilename:
        """
        self.fileName = infilename
        self._get_rasterinfo()

    def _get_rasterinfo(self):
        """
          獲取柵格數據的行列數,波段數,放射矩陣,投影信息
          :return:
           @version <1.1> 2018-04-2 Wujd : Created.
        """
        self.dataset = gdal.Open(self.fileName)
        self.im_width = self.dataset.RasterXSize
        self.im_height = self.dataset.RasterYSize
        self.im_bands = self.dataset.RasterCount
        self.im_geotrans = self.dataset.GetGeoTransform()
        self.im_proj = self.dataset.GetProjection()
        self.im_data = self.dataset.ReadAsArray()

    def Translate_org(self,newfilename,orgparameter):
        """
        Translate方法設置INTERLEAVE=BAND or PIXEL ;只能設置BSQ和BIP
        :param newfilename:
        :param orgparameter:
        :return:
        """
        if orgparameter =="BSQ":
            gdal.Translate(newfilename, self.fileName, creationOptions=["INTERLEAVE=BAND"])
        else:
            gdal.Translate(newfilename, self.fileName, creationOptions=["INTERLEAVE=PIXEL"])
        return True

    def Translate_org_envi(self,newfilename,orgparameter):
        """
        轉換成ENVI格式,可以在INTERLEAVE= BSQ,BIL,BIP
        :param newfilename:
        :param orgparameter:
        :return:
        """
        #判斷數據類型
        if "int8" in self.im_data.dtype.name:
            datetype = gdal.GDT_Byte
        elif "int16" in self.im_data.dtype.name:
            datetype = gdal.GDT_UInt16
        else :
            datetype = gdal.GDT_Float32

        #創建ENVI格式的數據集,可直接設置INTERLEAVE爲"BIL,BIP,BSQ"
        driver = gdal.GetDriverByName("ENVI")

        if orgparameter =="BSQ":
            dataset = driver.Create(newfilename, self.im_width, self.im_height, self.im_bands,datetype,
                                    options=["INTERLEAVE=BSQ"])
        elif orgparameter =="BIL":
            dataset = driver.Create(newfilename, self.im_width, self.im_height, self.im_bands, datetype,
                                    options=["INTERLEAVE=BIL"])
        elif orgparameter =="BIP":
            dataset = driver.Create(newfilename, self.im_width, self.im_height, self.im_bands, datetype,
                                    options=["INTERLEAVE=BIP"])

        dataset.SetGeoTransform(self.im_geotrans)
        dataset.SetProjection(self.im_proj)

        try:
            for i in range(self.im_bands):
                dataset.GetRasterBand(i+1).WriteArray(self.im_data[i])
        except BaseException as e:
            print("數據寫入錯誤!"+str(e))

        return True

class ChangeDataType:
    def __init__(self, infilename):
        """
        初始化變量
        :param infilename:
        """
        self.fileName = infilename
        self._get_rasterinfo()

    def _get_rasterinfo(self):
        """
          獲取柵格數據的行列數,波段數,放射矩陣,投影信息
          :return:
           @version <1.1> 2018-04-2 Wujd : Created.
        """
        self.dataset = gdal.Open(self.fileName)
        self.im_width = self.dataset.RasterXSize
        self.im_height = self.dataset.RasterYSize
        self.im_bands = self.dataset.RasterCount
        self.im_geotrans = self.dataset.GetGeoTransform()
        self.im_proj = self.dataset.GetProjection()
        self.im_data = self.dataset.ReadAsArray()

    def getTranslateDtype(self,newfilename,parameter="float32"):
        """
        修改數據類型
        :param newfilename:
        :param parameter:
        :return:
        """
        list1 = ["byte","uint8","uint16","int16","uint32","int32","float32","float64","cint16","cint32","cfloat32","cfloat64"]
        list2 = [gdal.GDT_Byte,gdal.GDT_Byte,gdal.GDT_UInt16,gdal.GDT_Int16,gdal.GDT_UInt32,gdal.GDT_Int32,gdal.GDT_Float32,gdal.GDT_Float64,gdal.GDT_CInt16,gdal.GDT_CInt32,gdal.GDT_CFloat32,gdal.GDT_CFloat64]

        #調用公用的配置文件方法
        # obj = rwconfig.rwconfig()
        # try:
        #     datatype = obj.readconfig(parameter)
        # except ImportError:
        #     pass
        #
        # if datatype!=None:
        #     gdal.Translate(newfilename,self.fileName,outputType=datatype)

        if parameter.lower() in list1:
            gdal.Translate(newfilename,self.fileName,outputType=list2[list1.index(parameter)])

        return  True


# if __name__=="__main__":
#     path = r"F:\Wujd\0319Test\translate\GF2_clip_2000.tif"
#     obj1 = ChangeOrganization(path)
#     newpath = r"F:\Wujd\0319Test\translate\OutBand79"
#     outResult=obj1.Translate_org_envi(newpath,"BIL")
#     obj = ChangeDataType(path)
#     obj.getTranslateDtype(newpath,"int16")

gdal 讀取GTiff格式時,默認INTERLEAVE爲PIXEL,(BIP),而且INTERLEAVE must be PIXEL or BAND

在轉換使用envi格式進行轉換,可以在INTERLEAVE轉換成BIL,BIP,BSQ

http://www.gdal.org/frmt_gtiff.html
http://www.gdal.org/python/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章