[EDIT 1 - Tôi đã thay đổi tìm kiếm tọa độ pixel]
Sử dụng mẫu MODATML này mà bạn đã cung cấp và sử dụng thư viện gdal. Hãy mở hdf bằng gdal:
import gdal
dataset = gdal.Open(r"E:\modis\MODATML2.A2018182.0800.061.2018182195418.hdf")
Sau đó, chúng tôi muốn xem cách các tập hợp con được đặt tên để nhập chính xác những cái chúng tôi cần:
datasets_meta = dataset.GetMetadata("SUBDATASETS")
Điều này trả về một từ điển:
datasets_meta
>>>{'SUBDATASET_1_NAME': 'HDF4_EOS:EOS_SWATH:"E:\\modis\\MODATML2.A2018182.0800.061.2018182195418.hdf":atml2:Cloud_Optical_Thickness',
'SUBDATASET_1_DESC': '[406x271] Cloud_Optical_Thickness atml2 (16-bit integer)',
'SUBDATASET_2_NAME':'HDF4_EOS:EOS_SWATH:"E:\\modis\\MODATML2.A2018182.0800.061.2018182195418.hdf":atml2:Cloud_Effective_Radius',
'SUBDATASET_2_DESC': '[406x271] Cloud_Effective_Radius atml2 (16-bit integer)',
[....]}
Giả sử chúng ta muốn lấy biến đầu tiên, độ dày quang học đám mây, chúng ta có thể truy cập tên của nó bằng cách:
datasets_meta['SUBDATASET_1_NAME']
>>>'HDF4_EOS:EOS_SWATH:"E:\\modis\\MODATML2.A2018182.0800.061.2018182195418.hdf":atml2:Cloud_Optical_Thickness'
Bây giờ chúng ta có thể tải biến trong bộ nhớ gọi lại phương thức .Open ():
Cloud_opt_th = gdal.Open(datasets_meta['SUBDATASET_1_NAME'])
Ví dụ: bạn có thể truy cập Precipitable_Water_Infrared_ClearSky mà bạn quan tâm bằng cách cung cấp 'SUBDATASET_20_NAME'. Chỉ cần nhìn vào từ điển dataets_meta.
Tuy nhiên, biến được trích xuất không có tính năng geoprojection (var.GetGeoprojection ()) như bạn mong đợi từ các loại tệp khác như GeoTiff. Bạn có thể tải biến dưới dạng một mảng numpy và vẽ biến 2d mà không cần chiếu:
Cloud_opt_th_array = Cloud_opt_th.ReadAsArray()
import matplotlib.pyplot as plt
plt.imshow(Cloud_opt_th_array)
Bây giờ, vì không có địa vật lý, chúng ta sẽ xem xét siêu dữ liệu của biến:
Cloud_opt_th_meta = Cloud_opt_th.GetMetadata()
Đây là một từ điển khác Bao gồm tất cả thông tin bạn cần, bao gồm một mô tả dài về mẫu phụ (tôi nhận thấy điều này chỉ được cung cấp với tập hợp con đầu tiên), bao gồm phần giải thích về các Cell_Along_Swath này:
Cloud_opt_th_meta['1_km_to_5_km_subsampling_description']
>>>'Each value in this dataset does not represent an average of properties over a 5 x 5 km grid box, but rather a single sample from within each 5 km box. Normally, pixels in across-track rows 4 and 9 (counting in the direction of increasing scan number) out of every set of 10 rows are used for subsampling the 1 km retrievals to a 5 km resolution. If the array contents are determined to be all fill values after selecting the default pixel subset (e.g., from failed detectors), a different pair of pixel rows is used to perform the subsampling. Note that 5 km data sets are centered on rows 3 and 8; the default sampling choice of 4 and 9 is for better data quality and avoidance of dead detectors on Aqua. The row pair used for the 1 km sample is always given by the first number and last digit of the second number of the attribute Cell_Along_Swath_Sampling. The attribute Cell_Across_Swath_Sampling indicates that columns 3 and 8 are used, as they always are, for across-track sampling. Again these values are to be interpreted counting in the direction of the scan, from 1 through 10 inclusively. For example, if the value of attribute Cell_Along_Swath_Sampling is 3, 2028, 5, then the third and eighth pixel rows were used for subsampling. A value of 4, 2029, 5 indicates that the default fourth and ninth rows pair was used.'
Tôi nghĩ điều này có nghĩa là dựa trên các pixel 1km này, 5km được xây dựng lấy chính xác các giá trị pixel ở một vị trí nhất định trong mảng cảm biến 5x5 (vị trí được chỉ định trong siêu dữ liệu, tôi nghĩ rằng đây là một công cụ để giảm lỗi).
Nhưng dù sao, tại thời điểm này, chúng ta có một loạt các ô 1x1 km (xem mô tả về mẫu phụ ở trên, không chắc chắn về khoa học đằng sau nó). Để có được tọa độ của từng pixel pixel, chúng ta cần tải các tập hợp con vĩ độ và kinh độ.
Latitude = gdal.Open(datasets_meta['SUBDATASET_66_NAME']).ReadAsArray()
Longitude = gdal.Open(datasets_meta['SUBDATASET_67_NAME']).ReadAsArray()
Ví dụ,
Longitude
>>> array([[-133.92064, -134.1386 , -134.3485 , ..., -154.79303, -154.9963 ,
-155.20723],
[-133.9295 , -134.14743, -134.3573 , ..., -154.8107 , -155.01431,
-155.2256 ],
[-133.93665, -134.1547 , -134.36465, ..., -154.81773, -155.02109,
-155.23212],
...,
[-136.54477, -136.80055, -137.04684, ..., -160.59378, -160.82101,
-161.05663],
[-136.54944, -136.80536, -137.05179, ..., -160.59897, -160.8257 ,
-161.06076],
[-136.55438, -136.81052, -137.05714, ..., -160.6279 , -160.85527,
-161.09099]], dtype=float32)
Bạn có thể nhận thấy rằng tọa độ Vĩ độ và Kinh độ là khác nhau đối với mỗi pixel.
Giả sử đài quan sát của bạn được đặt tại tọa độ lat_obs, long_obs, hơn là bạn giảm thiểu chênh lệch tọa độ x, y:
coordinates = np.unravel_index((np.abs(Latitude - lat_obs) + np.abs(Longitude - long_obs)).argmin(), Latitude.shape)
và trích xuất giá trị của bạn
Cloud_opt_th_array[coordinates]