Python Cartopy 中的 LSA-SAF 卫星 HDF5 图
LSA-SAF Satellite HDF5 Plot in Python Cartopy
我有一些 LSA-SAF HDF5 文件数据,我希望最终用 Cartopy 在 Python 中绘制它。我对 HDF5 文件的经验为零,所以我可能会在这里树错树,但我可以绘制数据和地图。主要问题是预测不一致。我试过弄乱子图和 imshow 变换参数中的投影。由于 MSG 数据似乎没有地理定位,所以我可能无法轻松完成我希望的事情。
我的代码:
FILE_NAME = 'HDF5_LSASAF_MSG_LAI_MSG-Disk_201806010000.h5' #LAI
crs = ccrs.Geostationary(central_longitude=0.0,satellite_height= 35785831)
crs2 = ccrs.PlateCarree(central_longitude=0.0) #central_longitude=0.0
fig = plt.figure(figsize=(10, 12))
ax = fig.add_subplot(1, 1, 1, projection=crs)
f = h5py.File(FILE_NAME, mode='r')
key_list = f.keys()
key_list2 = []
key_list2.append(key_list[0])
for key in key_list2:
print(key)
matrix = f.get(key)
ax.add_feature(cfeature.COASTLINE.with_scale('50m'), linewidth=0.75)
ax.add_feature(cfeature.BORDERS.with_scale('50m'), linewidth=0.5)
ax.add_feature(cfeature.OCEAN.with_scale('50m'),alpha=0.2)
cmap=cm.YlGn
cmap.set_bad(alpha=0.0)
img_extent = (-65,65,-65,65)
ax.imshow(matrix[:], cmap=cmap, norm=colors.Normalize(vmin=-1.0,
vmax=7000.0), origin='upper',extent=img_extent,transform=crs2)
plt.show()
我在尝试绘制 GOES-16 数据时遇到了类似的问题,并通过计算纬度和经度的卫星高度解决了这个问题。我对 HDF5 文件层次结构了解不够,无法找到 MSG 地球同步卫星的类似数据。任何关于这是否可以实现的见解 and/or HDF5 数据将不胜感激。
正如 tda 提到的,我在 gdal
方面也取得了成功。我在这里使用的是 FAPAR 产品。
in_pathfiles = '/path/to/HDF5 files/*FAPAR*.h5' # Where .hdf5 files exist
out_pathfiles = '/path/to/new geotiff files/' # Where the new .tif file will be placed
myfiles = glob.glob(in_pathfiles) #list of all files
for f in myfiles:
print(f),"\n"
filename = f.split("\")[-1]
print "filename",out_pathfiles+filename,"\n"
f_out = filename[:-3] + ".tif" # splitting the .hd5 off the fileneame and making a new .tif filename
print "f_out",out_pathfiles+f_out,"\n"
f_rep = out_pathfiles+filename[:-3] + "_rep.tif" # create a new final .tif filename for reprojection
print "f_rep",f_rep,"\n"
# Translating the satellite height and ellipitical values to xy values and filling the new _rep.tif file
# from the original .h5 file
os.system('gdal_translate -of GTiff -a_srs "+proj=geos +h=35785831 +a=6378169 +b=6356583.8 +no_defs"\
-a_ullr -5568748.27576 5568748.27576 5568748.27576 -5568748.27576 "HDF5:'+ filename + '://FAPAR '+ f_out)
# Mapping the new values and filling the new _rep.tif file
os.system('gdalwarp -ot Float32 -s_srs "+proj=geos +h=35785831 +a=6378169 +b=6356583.8 +no_defs"\
-t_srs EPSG:4326 -r near -of GTiff ' + f_out + ' ' + f_rep)
剧情:
# enable gdal exceptions (instead of the silent failure which is gdal default)
gdal.UseExceptions()
fname = "/path/to/rep.tif file/"
ds = gdal.Open(fname)
print( "[ RASTER BAND COUNT ]: ", ds.RasterCount)
cols = ds.RasterXSize
print('cols = ',cols)
rows = ds.RasterYSize
print(' rows = ', rows)
bands = ds.RasterCount
print('bands = ', bands)
driver = ds.GetDriver().LongName
print('driver =', driver)
print('MetaData = ',ds.GetMetadata())
Meta = ds.GetMetadata()
#print Meta.values()
Product = Meta.values()[3]
print Product
# print various metadata for the image
geotransform = ds.GetGeoTransform()
if not geotransform is None:
print ('Origin = (',geotransform[0], ',',geotransform[3],')')
print ('Pixel Size = (',geotransform[1], ',',geotransform[5],')')
proj = ds.GetProjection()
print proj
inproj = osr.SpatialReference()
inproj.ImportFromWkt(proj)
print('inproj = \n', inproj)
data = ds.ReadAsArray()
crs = ccrs.Geostationary(central_longitude=0.0)
crs2 = ccrs.PlateCarree(central_longitude=0.0)
fig = plt.figure(figsize=(10, 12))
ax = fig.add_subplot(1, 1, 1, projection=crs)
ax.add_feature(cfeature.COASTLINE.with_scale('50m'), linewidth=0.75)
ax.add_feature(cfeature.BORDERS.with_scale('50m'), linewidth=0.5)
ax.add_feature(cfeature.OCEAN.with_scale('50m'),alpha=0.2)
cmap=cm.YlGn
cmap.set_bad(alpha=0.0)
#ax.set_extent([-60,60,-60,60])
img_extent = (-81.26765645410755,81.26765645410755,-74.11423113858775,74.11423113858775)
ax.imshow(data, cmap=cmap, norm=colors.Normalize(vmin=-1.0, vmax=7000.0), origin='upper'
,extent=img_extent,transform=crs2)
plt.show()
为数据为 0 的地方绘制一个新区域和掩码数组。这让我可以显示海洋和其他数据不相关的区域:
fig = plt.figure(figsize=(10, 12))
# enable gdal exceptions (instead of the silent failure which is gdal default)
gdal.UseExceptions()
fname = "/path/to/rep.tif file/"
ds = gdal.Open(fname)
Meta = ds.GetMetadata()
Product = Meta.values()[3]
#print Product
Date = Meta.values()[38]
Date_End = Date[:8]
geotransform = ds.GetGeoTransform()
data = ds.ReadAsArray()
data = np.ma.masked_where(data <= -1, data)
crs = ccrs.Geostationary(central_longitude=0.0)
crs2 = ccrs.PlateCarree(central_longitude=0.0)
ax = fig.add_subplot(1, 1, 1, projection=crs2)
gl = ax.gridlines(crs=crs2, draw_labels=True,
linewidth=2, color='gray', alpha=0.5, linestyle='--')
gl.xlabels_top = False
gl.ylabels_left = False
ax.add_feature(cfeature.COASTLINE.with_scale('50m'), linewidth=0.75)
ax.add_feature(cfeature.BORDERS.with_scale('50m'), linewidth=0.5)
cmap=cm.YlGn
cmap.set_bad(alpha=0.0)
ax.set_extent([5,40,-10,8]) # Congo
img_extent = (-81.26765645410755,81.26765645410755,-74.11423113858775,74.11423113858775)
cf = ax.imshow(data, cmap="RdYlGn", origin='upper'
,extent=img_extent,transform=crs2)
cbar = plt.colorbar(cf, orientation='horizontal')
ax.add_feature(cfeature.OCEAN.with_scale('50m'),alpha=0.5)
plt.show()
我有一些 LSA-SAF HDF5 文件数据,我希望最终用 Cartopy 在 Python 中绘制它。我对 HDF5 文件的经验为零,所以我可能会在这里树错树,但我可以绘制数据和地图。主要问题是预测不一致。我试过弄乱子图和 imshow 变换参数中的投影。由于 MSG 数据似乎没有地理定位,所以我可能无法轻松完成我希望的事情。
我的代码:
FILE_NAME = 'HDF5_LSASAF_MSG_LAI_MSG-Disk_201806010000.h5' #LAI
crs = ccrs.Geostationary(central_longitude=0.0,satellite_height= 35785831)
crs2 = ccrs.PlateCarree(central_longitude=0.0) #central_longitude=0.0
fig = plt.figure(figsize=(10, 12))
ax = fig.add_subplot(1, 1, 1, projection=crs)
f = h5py.File(FILE_NAME, mode='r')
key_list = f.keys()
key_list2 = []
key_list2.append(key_list[0])
for key in key_list2:
print(key)
matrix = f.get(key)
ax.add_feature(cfeature.COASTLINE.with_scale('50m'), linewidth=0.75)
ax.add_feature(cfeature.BORDERS.with_scale('50m'), linewidth=0.5)
ax.add_feature(cfeature.OCEAN.with_scale('50m'),alpha=0.2)
cmap=cm.YlGn
cmap.set_bad(alpha=0.0)
img_extent = (-65,65,-65,65)
ax.imshow(matrix[:], cmap=cmap, norm=colors.Normalize(vmin=-1.0,
vmax=7000.0), origin='upper',extent=img_extent,transform=crs2)
plt.show()
我在尝试绘制 GOES-16 数据时遇到了类似的问题,并通过计算纬度和经度的卫星高度解决了这个问题。我对 HDF5 文件层次结构了解不够,无法找到 MSG 地球同步卫星的类似数据。任何关于这是否可以实现的见解 and/or HDF5 数据将不胜感激。
正如 tda 提到的,我在 gdal
方面也取得了成功。我在这里使用的是 FAPAR 产品。
in_pathfiles = '/path/to/HDF5 files/*FAPAR*.h5' # Where .hdf5 files exist
out_pathfiles = '/path/to/new geotiff files/' # Where the new .tif file will be placed
myfiles = glob.glob(in_pathfiles) #list of all files
for f in myfiles:
print(f),"\n"
filename = f.split("\")[-1]
print "filename",out_pathfiles+filename,"\n"
f_out = filename[:-3] + ".tif" # splitting the .hd5 off the fileneame and making a new .tif filename
print "f_out",out_pathfiles+f_out,"\n"
f_rep = out_pathfiles+filename[:-3] + "_rep.tif" # create a new final .tif filename for reprojection
print "f_rep",f_rep,"\n"
# Translating the satellite height and ellipitical values to xy values and filling the new _rep.tif file
# from the original .h5 file
os.system('gdal_translate -of GTiff -a_srs "+proj=geos +h=35785831 +a=6378169 +b=6356583.8 +no_defs"\
-a_ullr -5568748.27576 5568748.27576 5568748.27576 -5568748.27576 "HDF5:'+ filename + '://FAPAR '+ f_out)
# Mapping the new values and filling the new _rep.tif file
os.system('gdalwarp -ot Float32 -s_srs "+proj=geos +h=35785831 +a=6378169 +b=6356583.8 +no_defs"\
-t_srs EPSG:4326 -r near -of GTiff ' + f_out + ' ' + f_rep)
剧情:
# enable gdal exceptions (instead of the silent failure which is gdal default)
gdal.UseExceptions()
fname = "/path/to/rep.tif file/"
ds = gdal.Open(fname)
print( "[ RASTER BAND COUNT ]: ", ds.RasterCount)
cols = ds.RasterXSize
print('cols = ',cols)
rows = ds.RasterYSize
print(' rows = ', rows)
bands = ds.RasterCount
print('bands = ', bands)
driver = ds.GetDriver().LongName
print('driver =', driver)
print('MetaData = ',ds.GetMetadata())
Meta = ds.GetMetadata()
#print Meta.values()
Product = Meta.values()[3]
print Product
# print various metadata for the image
geotransform = ds.GetGeoTransform()
if not geotransform is None:
print ('Origin = (',geotransform[0], ',',geotransform[3],')')
print ('Pixel Size = (',geotransform[1], ',',geotransform[5],')')
proj = ds.GetProjection()
print proj
inproj = osr.SpatialReference()
inproj.ImportFromWkt(proj)
print('inproj = \n', inproj)
data = ds.ReadAsArray()
crs = ccrs.Geostationary(central_longitude=0.0)
crs2 = ccrs.PlateCarree(central_longitude=0.0)
fig = plt.figure(figsize=(10, 12))
ax = fig.add_subplot(1, 1, 1, projection=crs)
ax.add_feature(cfeature.COASTLINE.with_scale('50m'), linewidth=0.75)
ax.add_feature(cfeature.BORDERS.with_scale('50m'), linewidth=0.5)
ax.add_feature(cfeature.OCEAN.with_scale('50m'),alpha=0.2)
cmap=cm.YlGn
cmap.set_bad(alpha=0.0)
#ax.set_extent([-60,60,-60,60])
img_extent = (-81.26765645410755,81.26765645410755,-74.11423113858775,74.11423113858775)
ax.imshow(data, cmap=cmap, norm=colors.Normalize(vmin=-1.0, vmax=7000.0), origin='upper'
,extent=img_extent,transform=crs2)
plt.show()
为数据为 0 的地方绘制一个新区域和掩码数组。这让我可以显示海洋和其他数据不相关的区域:
fig = plt.figure(figsize=(10, 12))
# enable gdal exceptions (instead of the silent failure which is gdal default)
gdal.UseExceptions()
fname = "/path/to/rep.tif file/"
ds = gdal.Open(fname)
Meta = ds.GetMetadata()
Product = Meta.values()[3]
#print Product
Date = Meta.values()[38]
Date_End = Date[:8]
geotransform = ds.GetGeoTransform()
data = ds.ReadAsArray()
data = np.ma.masked_where(data <= -1, data)
crs = ccrs.Geostationary(central_longitude=0.0)
crs2 = ccrs.PlateCarree(central_longitude=0.0)
ax = fig.add_subplot(1, 1, 1, projection=crs2)
gl = ax.gridlines(crs=crs2, draw_labels=True,
linewidth=2, color='gray', alpha=0.5, linestyle='--')
gl.xlabels_top = False
gl.ylabels_left = False
ax.add_feature(cfeature.COASTLINE.with_scale('50m'), linewidth=0.75)
ax.add_feature(cfeature.BORDERS.with_scale('50m'), linewidth=0.5)
cmap=cm.YlGn
cmap.set_bad(alpha=0.0)
ax.set_extent([5,40,-10,8]) # Congo
img_extent = (-81.26765645410755,81.26765645410755,-74.11423113858775,74.11423113858775)
cf = ax.imshow(data, cmap="RdYlGn", origin='upper'
,extent=img_extent,transform=crs2)
cbar = plt.colorbar(cf, orientation='horizontal')
ax.add_feature(cfeature.OCEAN.with_scale('50m'),alpha=0.5)
plt.show()