[편집 1-픽셀 좌표 검색을 변경했습니다]
제공 한이 MODATML 샘플 사용 및 gdal 라이브러리 사용. gdal로 hdf를 열자 :
import gdal
dataset = gdal.Open(r"E:\modis\MODATML2.A2018182.0800.061.2018182195418.hdf")
그런 다음 필요한 데이터를 올바르게 가져 오기 위해 서브 데이터 세트의 이름이 어떻게 지정되는지 확인하려고합니다.
datasets_meta = dataset.GetMetadata("SUBDATASETS")
사전을 반환합니다.
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)',
[....]}
첫 번째 변수 인 클라우드 광학 두께를 얻고 싶다면 다음과 같이 이름에 액세스 할 수 있습니다.
datasets_meta['SUBDATASET_1_NAME']
>>>'HDF4_EOS:EOS_SWATH:"E:\\modis\\MODATML2.A2018182.0800.061.2018182195418.hdf":atml2:Cloud_Optical_Thickness'
이제 메모리에서 변수를 다시로드하여 .Open () 메서드를 다시 호출 할 수 있습니다.
Cloud_opt_th = gdal.Open(datasets_meta['SUBDATASET_1_NAME'])
예를 들어, 'SUBDATASET_20_NAME'을 제공하여 관심있는 Precipitable_Water_Infrared_ClearSky에 액세스 할 수 있습니다. datasets_meta 사전을 살펴보십시오.
그러나 추출 된 변수에는 GeoTiff와 같은 다른 파일 형식에서 예상 할 수있는 geoprojection (var.GetGeoprojection ())이 없습니다. 변수를 numpy 배열로로드하고 투영없이 2D 변수를 플롯 할 수 있습니다.
Cloud_opt_th_array = Cloud_opt_th.ReadAsArray()
import matplotlib.pyplot as plt
plt.imshow(Cloud_opt_th_array)
지리 투영법이 없으므로 변수의 메타 데이터를 살펴 보겠습니다.
Cloud_opt_th_meta = Cloud_opt_th.GetMetadata()
이것은 서브 샘플링에 대한 긴 설명을 포함하여 필요한 모든 정보를 포함하는 또 다른 사전입니다 (이것은 첫 번째 하위 데이터 세트에만 제공되는 것을 알았습니다).이 Cell_Along_Swath에 대한 설명이 포함되어 있습니다.
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.'
이것은이 1km 픽셀을 기반으로 5km가 5x5 감지 배열의 특정 위치에서 픽셀 값을 정확하게 가져 와서 만들어진다는 것을 의미한다고 생각합니다 (위치는 메타 데이터에 표시되어 있습니다. 이것은 결함을 줄이는 계기라고 생각합니다).
어쨌든,이 시점에서 우리는 1x1km의 셀 배열을 가지고 있습니다 (위의 서브 샘플링에 대한 설명은 그 뒤에 과학에 대해서는 확실하지 않습니다). 각 픽셀 중심의 좌표를 얻으려면 위도 및 경도 하위 데이터 집합을로드해야합니다.
Latitude = gdal.Open(datasets_meta['SUBDATASET_66_NAME']).ReadAsArray()
Longitude = gdal.Open(datasets_meta['SUBDATASET_67_NAME']).ReadAsArray()
예를 들어
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)
위도 및 경도 좌표가 각 픽셀마다 다름을 알 수 있습니다.
관측소가 x, y 좌표 차이를 최소화하는 것보다 lat_obs, long_obs 좌표에 있다고 가정하십시오.
coordinates = np.unravel_index((np.abs(Latitude - lat_obs) + np.abs(Longitude - long_obs)).argmin(), Latitude.shape)
그리고 당신의 가치를 추출
Cloud_opt_th_array[coordinates]