-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprocess_MODISNDSI.py
More file actions
162 lines (131 loc) · 6.96 KB
/
process_MODISNDSI.py
File metadata and controls
162 lines (131 loc) · 6.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# -*- coding: utf-8 -*-
"""
Python script for extracting Normalized Difference Snow Index (NDSI) snow cover raster map from MODIS data
Created on Thu Apr 16 17:09:18 2020
@author: FY
"""
from osgeo import gdal
import numpy as np
import os
import glob
import subprocess
import pandas as pd
import datetime
#This script is created to automate the process of producing NDSI snow cover map for Alaska from MODIS. The major
#processes include the selectin of date range based on the input hdf files, extract NDSI sublayer, reproject to WGS84 GCS
#and merge the result into one raster file for Alaska in geotiff format.
def extract_filename(startdate_,enddate_,filetyp_,inputpath_,sensordataheader_):
"""Extract the name list of the hdf files and the GeoTiff files by the date range"""
#Create a pattern based on the file name to filter the results
#e.g., MOD10A1.A2016001.h23v02.006.2016183123607.hdf: Year+Julian Day
pattern = os.path.join(inputpath_,sensordataheader_+".A" + "{:04}" + "{:03}" + filetyp_)
delta1=datetime.timedelta(days=1)
delta=enddate_-startdate_
if filetyp_=="*.hdf" and startdate_ <= enddate_:
l=[]
for i in range(delta.days + 1):
date = startdate_ + i*delta1
#Extract year and julian day
wildcard = pattern.format(date.year,int(date.strftime('%j')))
#Store the filename in a list
for filename in glob.glob(wildcard):
l.append(filename)
return (l)
elif filetyp_=="*.tif" and startdate_ <= enddate_:
l=[]
dates=[]
for i in range(delta.days + 1):
date = startdate_ + i*delta1
#Extract year and julian day
wildcard = pattern.format(date.year,int(date.strftime('%j')))
l_1=[]
for filename in glob.glob(wildcard):
#Store the filename in a list (sublist is for merging the raster at the same day)
l_1.append(filename)
#Exclude these days without any swath
if len(l_1)!=0:
l.append(l_1)
dates.append(date)
return (l,dates)
else:
print ("Please provide correct start/end data or correct file type")
return ()
def hdf_subdataset_extraction(hdflist_, tiffoutdir_, subdataset_):
"""unpack a single subdataset from a HDF5 container and write to GeoTiff"""
for i in hdflist_:
# open the dataset
hdf_ds = gdal.Open(i, gdal.GA_ReadOnly)
band_ds = gdal.Open(hdf_ds.GetSubDatasets()[subdataset_][0], gdal.GA_ReadOnly)
# read into numpy array
band_array = band_ds.ReadAsArray().astype(np.uint8)
# build output path
band_path = os.path.join(tiffoutdir_, os.path.basename(os.path.splitext(i)[0]) + "-sd_" + str(subdataset_) + "_.tif")
# write raster
out_ds = gdal.GetDriverByName('GTiff').Create(band_path,
band_ds.RasterXSize,
band_ds.RasterYSize,
1, #Number of bands
gdal.GDT_Byte, #Data type int8
['COMPRESS=LZW', 'TILED=YES'])
out_ds.SetGeoTransform(band_ds.GetGeoTransform())
out_ds.SetProjection(band_ds.GetProjection())
out_ds.GetRasterBand(1).WriteArray(band_array)
out_ds.GetRasterBand(1).SetNoDataValue(255)
#close dataset to write to disc
out_ds = None
return ()
def merge_tiff(tifffile_,tiffdate_,tiffoutdir_,tiffoutdirfinal_,proj_,sensordataheader_):
"""Merge the GeoTiff files of different swath on the same day"""
#Define the detailed paramters for gdal.Translate and gdal.Warp
kwargs0={'format' : 'GTiff', 'outputType':gdal.GDT_Byte,'creationOptions': ['COMPRESS=LZW', 'TILED=YES']}
kwargs1 = {'dstSRS':os.path.join(os.path.dirname(proj_),os.path.basename(proj_)[:-4]+'.prj'), 'xRes': 500,'yRes': 500,
'multithread': True, 'format': 'GTiff', 'cutlineDSName' : proj_ , 'cropToCutline':True, 'creationOptions': ['COMPRESS=LZW', 'TILED=YES']}
for i,v in enumerate(tifffile_):
#Create a filelist to merge the tiffs on the same day (different spatial coverage)
datestr=sensordataheader_+".A"+str(tiffdate_[i].year)+str(tiffdate_[i].month).zfill(2)+str(tiffdate_[i].day).zfill(2)
filelist=os.path.join(tiffoutdirfinal_,datestr+'.txt')
with open(filelist, 'w') as filehandle:
filehandle.writelines("%s\n" % tiff for tiff in v)
output_vitural=os.path.join(tiffoutdir_,datestr+'.vrt')
output_merge=os.path.join(tiffoutdir_,datestr+'.tif')
output_clip=os.path.join(tiffoutdirfinal_,datestr+'.tif')
#Build a virtual raster for each date
vrt = gdal.BuildVRT(output_vitural, [tiff for tiff in v])
vrt = None
#Translate the virtual raster to tiff file
pro=gdal.Translate(output_merge, output_vitural, **kwargs0)
pro=None
#Reproject the virtual raster and generate tiff file (resolution 500 m) and corp the resuts to the interested region and generate output
out=gdal.Warp(output_clip, output_merge, **kwargs1)
out=None
#Delete the merged files (upcroped) from disk
os.remove(output_merge)
return ()
if __name__ == '__main__':
#User input path including the downloaded hdf files for MODIS, start date and end date YYYY-MM-DD
inputpath='F:/modis/netcdf'
startdate='2016-01-01'
enddate='2016-01-15'
#Input polygon for processing extent
inputshp='F:/modis/crop/Alaska.shp'
#Input sensor data header
sensordataheader='MYD10A1'
#Intermediate data storage path
tiffoutdir=os.path.join(os.path.dirname(inputpath),"tiff_process")
#Final data result storage path
tiffoutdirfinal=os.path.join(os.path.dirname(inputpath),"tiff_out")
if not os.path.exists(tiffoutdir):
os.mkdir(tiffoutdir)
os.mkdir(tiffoutdirfinal)
filetyp="*.hdf"
#Subset index of HDF file for MODIS NDSI (V6)
subdataset=0
startdate=pd.to_datetime(startdate, format='%Y-%m-%d')
enddate=pd.to_datetime(enddate, format='%Y-%m-%d')
hdflist=extract_filename(startdate, enddate, filetyp, inputpath, sensordataheader)
#Extract subdataset from HDF files
hdf_subdataset_extraction(hdflist, tiffoutdir, subdataset)
#Extract the list of tiff files and corresponding dates
tifflist,tiffdate=extract_filename(startdate,enddate,"*.tif",tiffoutdir,sensordataheader)
#Merge and reproject the tiff files
merge_tiff(tifflist,tiffdate,tiffoutdir,tiffoutdirfinal,inputshp,sensordataheader)