Himawari 8數據介紹及下載轉換
1.Himawari-8衛星簡介
日本發射的靜止軌道衛星。JMA於2015年7月7日開始運營Himawari-8, Himawari-9號衛星於2017年3月10日開始后備運行。兩顆衛星都位於向東約140.7度的軌道上,並將觀測東亞和西太平洋區域15年。
2. 衛星特性介紹
重訪周期短(10min),光譜分辨率高,主傳感器為AHI,常用於氣象觀測。
3. 衛星數據格式介紹
這里僅討論L1級數據。FTP上分享的數據有.nc、.dat(HSD)兩種格式。
1. nc
# Available Himawari L1 Gridded Data
## Full-disk
Projection: EQR
Observation area: 60S-60N, 80E-160W
Temporal resolution: 10-minutes
Spatial resolution: 5km (Pixel number: 2401, Line number: 2401)
2km (Pixel number: 6001, Line number: 6001)
Data: albedo(reflectance*cos(SOZ) of band01~band06)
Brightness temperature of band07~band16
satellite zenith angle, satellite azimuth angle,
solar zenith angle, solar azimuth angle, observation hours (UT)
## Japan Area
Projection: EQR
Observation area: 23N-50N, 123E-150E
Temporal resolution: 10-minutes
Spatial resolution: 1km (Pixel number: 2701, Line number: 2601)
Data: albedo(reflectance*cos(SOZ) of band01~band06)
Brightness temperature of band07, 14, 15
satellite zenith angle, satellite azimuth angle,
solar zenith angle, solar azimuth angle, observation hours (UT)
主要分為兩個區域的數據,全圓盤、日本地區。這里僅討論全圓盤區域,影像空間分辨率一般為5km(2401行/列)/2km(6001行/列),該數據集包含的數據主要有:albedo(反射率 band1-6)、bt(亮溫 band 7-16)、太陽高度角/方位角、衛星高度角/方位角(可用於大氣校正)、lon、lat...
## Full-disk
NC_H08_YYYYMDD_hhmm_Rbb_FLDK.xxxxx_yyyyy.nc
where YYYY: 4-digit year of observation start time (timeline);
MM: 2-digit month of timeline;
DD: 2-digit day of timeline;
hh: 2-digit hour of timeline;
mm: 2-gidit minutes of timeline;
bb: 2-digit band number (varies from "01" to "16");
xxxxx: pixel number; ("2401": 5km resolution,
"6001": 2km resolution, )
yyyyy: line number; ("2401": 5km resolution,
"6001": 2km resolution, )
Example:
NC_H08_20160831_0000_R21_FLDK.02401_02401.nc
NC_H08_20160831_0000_R21_FLDK.06001_06001.nc
## Japan Area
NC_H08_YYYYMMDD_hhmm_rbb_FLDK.xxxxx_yyyyy.nc
where YYYY: 4-digit year of observation start time (timeline);
MM: 2-digit month of timeline;
DD: 2-digit day of timeline;
hh: 2-digit hour of timeline;
mm: 2-gidit minutes of timeline;
bb: 2-digit band number (fixed to "14");
xxxxx: pixel number; (fixed to "2701" : 1km resolution)
yyyyy: line number; (fixed to "2601" : 1km resolution)
Example:
NC_H08_20160831_0000_r14_FLDK.02701_02601.nc
以上是全圓盤數據的命名格式,其中NC_H08_YYYYMDD_hhmm_Rbb_FLDK.xxxxx_yyyyy.nc
注意R代表全球,而r代表日本,后面兩位代表分辨率。文件內的時間為UTC時間,跟北京時間相差8小時,簡單說UTC時間 = 北京時間 - 8小時
2. hsd
# Available Himawari Standard Data
## Full-disk
Observation area: Full-disk
Temporal resolution: 10-minutes
Spatial resolution: 0.5km (band 3), 1km (band 1,2,4), 2km (band 5-16)
## Japan Area
Observation area: Japan area (Region 1 & 2)
Temporal resolution: 2.5-minutes
Spatial resolution: 0.5km (band 3), 1km (band 1,2,4), 2km (band 5-16)
## Target Area
Observation area: Target area (Region 3)
Temporal resolution: 2.5-minutes
Spatial resolution: 0.5km (band 3), 1km (band 1,2,4), 2km (band 5-16)
## Color Image Data
png images of Full-disk, Japan area and Target area, compositing three visible
bands (blue: 0.47 micron; green: 0.51 micron; red: 0.64 micron).
數據結構暫時不詳,這里只看分辨率。分辨率全面優於nc,0.5km (band 3), 1km (band 1,2,4), 2km (band 5-16),最高達到了500m。提供的數據有全球、日本、目標區的影像及真彩圖。
where YYYY: 4-digit year of observation start time (timeline);
MM: 2-digit month of timeline;
DD: 2-digit day of timeline;
hh: 2-digit hour of timeline;
mm: 2-gidit minutes of timeline;
bb: 2-digit band number (varies from "01" to "16");
jj: spatial resolution ("05": 0.5km, "10": 1.0km, "20": 2.0km);
kk: segment number (varies from "01" to "10"); and
ll: total number of segments (fixed to "10").
example: HS_H08_20150728_2200_B01_FLDK_R10_S0110.DAT
在ftp中的存儲形式是一個波段一個dat文件。

4. 數據的自動下載及轉換
主要參考以下幾篇文章:https://blog.csdn.net/esa_dsq/article/details/105109487 、
https://blog.csdn.net/qq_44317919/article/details/108245097?ops_request_misc=%7B%22request%5Fid%22%3A%22160566320519724836713938%22%2C%22scm%22%3A%2220140713.130102334.pc%5Fall.%22%7D&request_id=160566320519724836713938&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~rank_v28_p-4-108245097.pc_first_rank_v2_rank_v28p&utm_term=himawari-8%E6%95%B0%E6%8D%AE%E8%87%AA%E5%8A%A8&spm=1018.2118.3001.4449
原文是選擇下載L3級AOD數據,這里筆者改成了下載L1級nc數據,數據下載到本地后入庫並轉換成tif,分別存入albedo/tbb
兩個子文件夾中。
Now, show u the main code.
-
核心模塊:下載ftp數據
class myFTP: ftp = ftplib.FTP() def __init__(self, host, port=21): ''' @desc:連接FTP,host是IP地址,port是端口,默認21 ''' self.ftp.connect(host, port) def Login(self, user, password): ''' @desc:登錄FTP連接,user是用戶名,password是密碼 ''' self.ftp.login(user, password) print(self.ftp.welcome) # 顯示登錄信息 def DownLoadFile(self, LocalFile, RemoteFile): ''' @desc:下載單個文件,LocalFile表示本地存儲路徑和文件名,RemoteFile是FTP路徑和文件名 ''' bufSize = 102400 file_handler = open(LocalFile, 'wb') print(file_handler) # 接收服務器上文件並寫入本地文件 self.ftp.retrbinary('RETR ' + RemoteFile, file_handler.write, bufSize) self.ftp.set_debuglevel(0) file_handler.close() return True def DownLoadFileTree(self, LocalDir, tifDir, RemoteDir, choice, dateStr): ''' @desc:下載整個目錄下的文件,LocalDir表示本地存儲路徑, RemoteDir表示FTP路徑 ''' # print("remoteDir:", RemoteDir) # 如果本地不存在該路徑,則創建 if not os.path.exists(LocalDir): os.makedirs(LocalDir) # 獲取FTP路徑下的全部文件名,以列表存儲 # 好像是亂序 self.ftp.cwd(RemoteDir) # 設置FTP當前操作的路徑 RemoteNames = self.ftp.nlst() # 獲取目錄下的文件 RemoteNames.reverse() # print("RemoteNames:", RemoteNames) for file in RemoteNames: # 先下載為臨時文件Local,下載完成后再改名為nc4格式的文件 # 這是為了防止上一次下載中斷后,最后一個下載的文件未下載完整,而再開始下載時,程序會識別為已經下載完成 Local = os.path.join(LocalDir, file[0:-3] + ".temp") LocalNew = os.path.join(LocalDir, file) ''' 下載小時文件,只下載UTC時間1時至9時(北京時間9時至17時)的文件 下載的文件必須是nc格式 若已經存在,則跳過下載 ''' # 小時數據命名格式示例:NC_H08_20201210_1300_R21_FLDK.06001_06001.nc # R代表全球區域,分辨率分為5KM/2KM兩種圖像 if choice == 1: if int(file[16:18]) >= 1 and int(file[16:18]) <= 9 and file[21]=='R': if not os.path.exists(LocalNew): print("Downloading the file of %s" % file) self.DownLoadFile(Local, file) os.rename(Local, LocalNew) print("The download of the file of %s has finished\n" % file) albedoPath, tbbPath = nc2tiff(LocalNew, tifDir) insert2database(file, LocalNew, albedoPath, tbbPath, dateStr) elif os.path.exists(LocalNew): print("The file of %s has already existed!\n" % file) else: pass self.ftp.cwd("..") # 設置FTP當前操作的路徑 return def close(self): self.ftp.quit()
該代碼塊是從上述鏈接中遷移而來,並且做了一定的修改。這里的難點只要在ftp命令的掌握和影像命名格式的熟悉,下面給出一些常用的ftp命令。
from ftplib import FTP #加載ftp模塊 #ftp登陸連接 ftp=FTP() #設置變量 ftp.set_debuglevel(2) #打開調試級別2,顯示詳細信息 ftp.connect("IP","port") #連接的ftp sever和端口 ftp.login("user","password") #連接的用戶名,密碼 ftp.getwelcome() #歡迎信息 ftp.cmd("xxx/xxx") #進入遠程目錄 bufsize=1024 #設置的緩沖區大小 filename="filename.txt" #需要下載的文件 file_handle=open(filename,"wb").write #以寫模式在本地打開文件 ftp.retrbinaly("RETR filename.txt",file_handle,bufsize) #接收服務器上文件並寫入本地文件 ftp.set_debuglevel(0) #關閉調試模式 ftp.quit() #退出ftp #ftp相關命令操作 ftp.cwd(pathname) #設置FTP當前操作的路徑 ftp.dir() #顯示目錄下所有目錄信息 ftp.nlst() #獲取目錄下的文件 ftp.mkd(pathname) #新建遠程目錄 ftp.pwd() #返回當前所在位置 ftp.rmd(dirname) #刪除遠程目錄 ftp.delete(filename) #刪除遠程文件 ftp.rename(fromname, toname) #將fromname修改名稱為toname。 ftp.storbinaly("STOR filename.txt",file_handel,bufsize) #上傳目標文件 ftp.retrbinary("RETR filename.txt",file_handel,bufsize) #下載FTP文件
常用的上傳及下載文件。
# !/usr/bin/python # -*- coding: utf-8 -*- from ftplib import FTP def ftpconnect(host, username, password): ftp = FTP() # ftp.set_debuglevel(2) ftp.connect(host, 21) ftp.login(username, password) return ftp #從ftp下載文件 def downloadfile(ftp, remotepath, localpath): bufsize = 1024 fp = open(localpath, 'wb') ftp.retrbinary('RETR ' + remotepath, fp.write, bufsize) ftp.set_debuglevel(0) fp.close() #從本地上傳文件到ftp def uploadfile(ftp, remotepath, localpath): bufsize = 1024 fp = open(localpath, 'rb') ftp.storbinary('STOR ' + remotepath, fp, bufsize) ftp.set_debuglevel(0) fp.close()
-
數據入庫(mysql)
def insert2database(ftpPath, filePath, albedoPath, tbbPath, dateTime): ''' @description:數據入庫png ''' #輸入數據庫的字段值 png_uuid = str(uuid.uuid1()) conn = pymysql.connect( db = 'himawari8', user = 'root', password = 'root', host = 'localhost', port = 3306 ) cur = conn.cursor() #首先查詢數據是否存在 #查詢影像對應的uuid是否存在 #新建表'downloadHimawari8',存放這些生成的數據 sql = 'SELECT uuid FROM ' + 'downloadHimawari8' + \ ' WHERE ftpPath=%s;' sql_data = (ftpPath) cur.execute(sql, sql_data) sql_res = cur.fetchall() if len(sql_res) == 0: print('正在入庫...') sql = 'INSERT INTO ' + 'downloadHimawari8' + \ ' (uuid,ftpPath,filePath,albedoPath,tbbPath,dateTime) VALUES (%s,%s,%s,%s,%s,%s);' sql_data = (png_uuid,ftpPath,filePath,albedoPath,tbbPath,dateTime) # print(sql%sql_data) cur.execute(sql, sql_data) conn.commit() else: print('[warning] 該文件已經存在,即將更新文件!') sql = 'UPDATE ' + 'downloadHimawari8' + \ ' SET uuid=%s,ftpPath=%s,filePath=%s,albedoPath=%s,tbbPath=%s,dateTime=%s;' sql_data = (png_uuid,ftpPath,filePath,albedoPath,tbbPath,dateTime) cur.execute(sql, sql_data) conn.commit() cur.close() conn.close()
注意:這里需要安裝mysql,參考https://www.cnblogs.com/winton-nfs/p/11524007.html
-
nc轉tif
def nc2tiff(ifile, outDir): ''' @desc: 只適用於Himawari-8 全球區域(R)對應的L1影像 讀取nc轉換成tif,生成同名albedo/tbb文件 @ifile: nc文件路徑 @outDir: 輸出路徑 ''' ds = h5py.File(ifile, mode='r') all_vars = list(ds.keys()) firstData = ds['albedo_01'][:] anotherData = ds['tbb_10'][:] lon = ds['longitude'][:] lat = ds['latitude'][:] count = 0 data1 = np.zeros((firstData.shape[0], firstData.shape[1], 6)) for var in all_vars: if var.startswith(str('albedo_')): data1[:,:,count] = ds[var][:] count = count + 1 count = 0 data2 = np.zeros((anotherData.shape[0], anotherData.shape[1], 10)) for var in all_vars: if var.startswith(str('tbb_')): data2[:,:,count] = ds[var][:] count = count + 1 xCell = (lon.max()-lon.min())/len(lon) yCell = (lat.max()-lat.min())/len(lat) geotrans = (lon.min(), xCell, 0, lat.max(), 0, -yCell) srs = osr.SpatialReference() srs.ImportFromEPSG(4326) proj = srs.ExportToWkt() albedoPath = os.path.join(outDir, 'albedoPath') tbbPath = os.path.join(outDir, 'tbbPath') if not os.path.exists(albedoPath): os.mkdir(albedoPath) if not os.path.exists(tbbPath): os.mkdir(tbbPath) albedoPath = os.path.join(albedoPath, os.path.basename(ifile).replace('.nc', '_albedo.tif')) tbbPath = os.path.join(tbbPath, os.path.basename(ifile).replace('.nc', '_tbb.tif')) raster2tif(data1, None, type(data1), geotrans, proj, albedoPath) raster2tif(data2, None, type(data2), geotrans, proj, tbbPath) return albedoPath, tbbPath
在讀取albedo/tbb數據集后,需要讀取lon/lat矩陣,計算出分辨率及起始點,來確定地理變換(geotrans)。設置好投影和仿射參數后,生成tif。
5. 結果展示

這樣我們就生成了對應的tif數據,完成了第一步。
6. 后續
幾點問題亟待解決
-
Himawari-8的輻射定標和大氣校正
2. **HSD**格式數據的解析
