[DÜZENLEME 1 - Piksel koordinat aramasını değiştirdim]
Sağladığınız bu MODATML örneğini ve gdal kütüphanesini kullanarak. HDF'yi gdal ile açalım:
import gdal
dataset = gdal.Open(r"E:\modis\MODATML2.A2018182.0800.061.2018182195418.hdf")
Ardından, ihtiyacımız olanları doğru bir şekilde içe aktarmak için alt veri kümelerinin nasıl adlandırıldığını görmek istiyoruz:
datasets_meta = dataset.GetMetadata("SUBDATASETS")
Bu bir sözlük döndürür:
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)',
[....]}
Diyelim ki ilk değişkeni, bulut optik kalınlığını elde etmek istiyoruz, adına şu şekilde erişebiliriz:
datasets_meta['SUBDATASET_1_NAME']
>>>'HDF4_EOS:EOS_SWATH:"E:\\modis\\MODATML2.A2018182.0800.061.2018182195418.hdf":atml2:Cloud_Optical_Thickness'
Şimdi değişkeni tekrar çağırarak belleğe yükleyebiliriz.
Cloud_opt_th = gdal.Open(datasets_meta['SUBDATASET_1_NAME'])
Örneğin, ilgilendiğiniz Precipitable_Water_Infrared_ClearSky öğesine 'SUBDATASET_20_NAME' sağlayarak erişebilirsiniz. Datasets_meta sözlüğüne bir göz atın.
Ancak, çıkarılan değişken, GeoTiff gibi diğer dosya türlerinden beklediğiniz gibi bir coğrafi projeksiyona (var.GetGeoprojection ()) sahip değildir. Değişkeni bir numpy dizisi olarak yükleyebilir ve 2d değişkenini izdüşüm olmadan çizebilirsiniz:
Cloud_opt_th_array = Cloud_opt_th.ReadAsArray()
import matplotlib.pyplot as plt
plt.imshow(Cloud_opt_th_array)
Şimdi, coğrafi projeksiyon olmadığından, değişkenin meta verilerine bakacağız:
Cloud_opt_th_meta = Cloud_opt_th.GetMetadata()
Bu, Cell_Along_Swath'in açıklamasını içeren alt örneklemenin uzun bir açıklaması da dahil olmak üzere ihtiyacınız olan tüm bilgileri içeren başka bir sözlüktür (bunun yalnızca ilk alt veri kümesiyle sağlandığını fark ettim):
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.'
Bence bu 1km piksellerine dayanarak 5km, 5x5 algılama dizisinde belirli bir pozisyonda tam olarak piksel değerlerini alarak oluşturulmuştur (konum meta verilerde gösterilir, bence bu hataları azaltmak için bir araçtır).
Her neyse, bu noktada 1x1 km'lik bir hücre dizimiz var (yukarıdaki alt örneklemenin açıklamasına bakın, arkasındaki bilimden emin değilim). Her piksel sentroidinin koordinatlarını elde etmek için enlem ve boylam alt veri kümelerini yüklememiz gerekir.
Latitude = gdal.Open(datasets_meta['SUBDATASET_66_NAME']).ReadAsArray()
Longitude = gdal.Open(datasets_meta['SUBDATASET_67_NAME']).ReadAsArray()
Örneğin,
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)
Enlem ve Boylam koordinatlarının her piksel için farklı olduğunu fark edebilirsiniz.
Gözlemcinizin x, y koordinat farkını en aza indirdiğinizden lat_obs, long_obs koordinatlarında bulunduğunu varsayalım:
coordinates = np.unravel_index((np.abs(Latitude - lat_obs) + np.abs(Longitude - long_obs)).argmin(), Latitude.shape)
ve değerini çıkar
Cloud_opt_th_array[coordinates]