How can I open a specific dataset (band) from a multi dataset MODIS image using Rasterio? Rasterio IndexError: band index out of range
How can I open a specific dataset (band) from a multi dataset MODIS image using Rasterio? Rasterio IndexError: band index out of range
如何使用 Rasterio 从多数据集 MODIS 图像中打开特定数据集?
我在 GitHub 上发布了一些示例数据:https://github.com/SteveObert/rasterIO_question/tree/master/data
如果我打开一个只有一个波段的 MODIS HDF 文件,下面的代码会按照我想要的方式工作:
import rasterio
rasterfileMulti = 'MOD10A1_multiband_HEGOUT.hdf'
rasterfileSingle = 'MOD10A1_singleband_HEGOUT.hdf'
shapeFile = 'SFP_drainage.shp'
# Read an HDF into an array
dataset = rasterio.open('rasterfileSingle')
band1 = dataset.read(1)
print(band1)
输出:
array([[ 53, 53, 250, ..., 255, 255, 255],
[ 56, 56, 56, ..., 255, 255, 255],
[ 56, 56, 49, ..., 255, 255, 255],
...,
[ 78, 78, 78, ..., 53, 50, 50],
[ 72, 78, 78, ..., 57, 57, 57],
[ 72, 72, 72, ..., 61, 61, 61]], dtype=uint8)
但是,如果我尝试打开包含多个数据集的 MODIS HDF 文件,我会收到如下错误 "Rasterio IndexError: band index out of range"。
rasterfileMulti = MOD10A1_multiband_HEGOUT.hdf
dataset2 = rasterio.open('rasterfileMulti')
band1 = dataset.read(1)
print(band1)
上面代码的错误如下所示:
/Users/steve/anaconda3/lib/python3.6/site-packages/rasterio/__init__.py:193: UserWarning: Dataset has no geotransform set. Default transform will be applied (Affine.identity())
s.start()
Traceback (most recent call last):
File "<ipython-input-9-584312f89d76>", line 3, in <module>
band1 = dataset.read(1)
File "rasterio/_io.pyx", line 720, in rasterio._io.RasterReader.read
IndexError: band index out of range
最终,我想将栅格裁剪到 shapefile。只要 Modis 图像只有一个波段,下面的代码就可以按照我想要的方式工作,在本例中为 'NDSI_Snow_Cover'。
import fiona
import rasterio
rasterfileSingle = MOD10A1_singleband_HEGOUT.hdf
shapeFile = SFP_drainage.shp
with fiona.open(shapeFile, 'r') as shapefile:
features = [feature['geometry'] for feature in shapefile]
with rasterio.open(rasterfileMulti) as src:
out_image, out_transform = rasterio.mask.mask(src, features,
crop=True)
out_meta = src.meta.copy()
out_meta.update({'driver': 'GTiff',
'height': out_image.shape[1],
'width': out_image.shape[2],
'transform': out_transform})
with rasterio.open('/Users/steve/Documents/classes/Geos_505/project_Payette/working/data_files/test_clip_out.tif', 'w', **out_meta) as dest:
dest.write(out_image)
首先,我们需要知道子数据集的名称。 gdalinfo 给出了以下 7 个子数据集:
Subdatasets:
SUBDATASET_1_NAME=HDF4_EOS:EOS_GRID:"MOD10A1_multiband_HEGOUT.hdf":MOD_Grid_Snow_500m_16:NDSI_Snow_Cover
SUBDATASET_1_DESC=[350x831] NDSI_Snow_Cover MOD_Grid_Snow_500m_16 (8-bit unsigned integer)
SUBDATASET_2_NAME=HDF4_EOS:EOS_GRID:"MOD10A1_multiband_HEGOUT.hdf":MOD_Grid_Snow_500m_16:NDSI_Snow_Cover_Basic_QA
SUBDATASET_2_DESC=[350x831] NDSI_Snow_Cover_Basic_QA MOD_Grid_Snow_500m_16 (8-bit unsigned integer)
SUBDATASET_3_NAME=HDF4_EOS:EOS_GRID:"MOD10A1_multiband_HEGOUT.hdf":MOD_Grid_Snow_500m_16:NDSI_Snow_Cover_Algorithm_Flags_QA
SUBDATASET_3_DESC=[350x831] NDSI_Snow_Cover_Algorithm_Flags_QA MOD_Grid_Snow_500m_16 (8-bit unsigned integer)
SUBDATASET_4_NAME=HDF4_EOS:EOS_GRID:"MOD10A1_multiband_HEGOUT.hdf":MOD_Grid_Snow_500m_16:NDSI
SUBDATASET_4_DESC=[350x831] NDSI MOD_Grid_Snow_500m_16 (16-bit integer)
SUBDATASET_5_NAME=HDF4_EOS:EOS_GRID:"MOD10A1_multiband_HEGOUT.hdf":MOD_Grid_Snow_500m_16:Snow_Albedo_Daily_Tile
SUBDATASET_5_DESC=[350x831] Snow_Albedo_Daily_Tile MOD_Grid_Snow_500m_16 (8-bit unsigned integer)
SUBDATASET_6_NAME=HDF4_EOS:EOS_GRID:"MOD10A1_multiband_HEGOUT.hdf":MOD_Grid_Snow_500m_16:orbit_pnt
SUBDATASET_6_DESC=[350x831] orbit_pnt MOD_Grid_Snow_500m_16 (8-bit integer)
SUBDATASET_7_NAME=HDF4_EOS:EOS_GRID:"MOD10A1_multiband_HEGOUT.hdf":MOD_Grid_Snow_500m_16:granule_pnt
SUBDATASET_7_DESC=[350x831] granule_pnt MOD_Grid_Snow_500m_16 (8-bit unsigned integer)
现在,您可以打开任何将子数据集的 GDAL 完全限定名称作为参数传递的子数据集。例如:
rasterio.open('HDF4_EOS:EOS_GRID:"MOD10A1_multiband_HEGOUT.hdf":MOD_Grid_Snow_500m_16:NDSI_Snow_Cover')
编辑:我根据作者的建议添加了外部单引号。
如何使用 Rasterio 从多数据集 MODIS 图像中打开特定数据集?
我在 GitHub 上发布了一些示例数据:https://github.com/SteveObert/rasterIO_question/tree/master/data
如果我打开一个只有一个波段的 MODIS HDF 文件,下面的代码会按照我想要的方式工作:
import rasterio
rasterfileMulti = 'MOD10A1_multiband_HEGOUT.hdf'
rasterfileSingle = 'MOD10A1_singleband_HEGOUT.hdf'
shapeFile = 'SFP_drainage.shp'
# Read an HDF into an array
dataset = rasterio.open('rasterfileSingle')
band1 = dataset.read(1)
print(band1)
输出:
array([[ 53, 53, 250, ..., 255, 255, 255],
[ 56, 56, 56, ..., 255, 255, 255],
[ 56, 56, 49, ..., 255, 255, 255],
...,
[ 78, 78, 78, ..., 53, 50, 50],
[ 72, 78, 78, ..., 57, 57, 57],
[ 72, 72, 72, ..., 61, 61, 61]], dtype=uint8)
但是,如果我尝试打开包含多个数据集的 MODIS HDF 文件,我会收到如下错误 "Rasterio IndexError: band index out of range"。
rasterfileMulti = MOD10A1_multiband_HEGOUT.hdf
dataset2 = rasterio.open('rasterfileMulti')
band1 = dataset.read(1)
print(band1)
上面代码的错误如下所示:
/Users/steve/anaconda3/lib/python3.6/site-packages/rasterio/__init__.py:193: UserWarning: Dataset has no geotransform set. Default transform will be applied (Affine.identity())
s.start()
Traceback (most recent call last):
File "<ipython-input-9-584312f89d76>", line 3, in <module>
band1 = dataset.read(1)
File "rasterio/_io.pyx", line 720, in rasterio._io.RasterReader.read
IndexError: band index out of range
最终,我想将栅格裁剪到 shapefile。只要 Modis 图像只有一个波段,下面的代码就可以按照我想要的方式工作,在本例中为 'NDSI_Snow_Cover'。
import fiona
import rasterio
rasterfileSingle = MOD10A1_singleband_HEGOUT.hdf
shapeFile = SFP_drainage.shp
with fiona.open(shapeFile, 'r') as shapefile:
features = [feature['geometry'] for feature in shapefile]
with rasterio.open(rasterfileMulti) as src:
out_image, out_transform = rasterio.mask.mask(src, features,
crop=True)
out_meta = src.meta.copy()
out_meta.update({'driver': 'GTiff',
'height': out_image.shape[1],
'width': out_image.shape[2],
'transform': out_transform})
with rasterio.open('/Users/steve/Documents/classes/Geos_505/project_Payette/working/data_files/test_clip_out.tif', 'w', **out_meta) as dest:
dest.write(out_image)
首先,我们需要知道子数据集的名称。 gdalinfo 给出了以下 7 个子数据集:
Subdatasets:
SUBDATASET_1_NAME=HDF4_EOS:EOS_GRID:"MOD10A1_multiband_HEGOUT.hdf":MOD_Grid_Snow_500m_16:NDSI_Snow_Cover
SUBDATASET_1_DESC=[350x831] NDSI_Snow_Cover MOD_Grid_Snow_500m_16 (8-bit unsigned integer)
SUBDATASET_2_NAME=HDF4_EOS:EOS_GRID:"MOD10A1_multiband_HEGOUT.hdf":MOD_Grid_Snow_500m_16:NDSI_Snow_Cover_Basic_QA
SUBDATASET_2_DESC=[350x831] NDSI_Snow_Cover_Basic_QA MOD_Grid_Snow_500m_16 (8-bit unsigned integer)
SUBDATASET_3_NAME=HDF4_EOS:EOS_GRID:"MOD10A1_multiband_HEGOUT.hdf":MOD_Grid_Snow_500m_16:NDSI_Snow_Cover_Algorithm_Flags_QA
SUBDATASET_3_DESC=[350x831] NDSI_Snow_Cover_Algorithm_Flags_QA MOD_Grid_Snow_500m_16 (8-bit unsigned integer)
SUBDATASET_4_NAME=HDF4_EOS:EOS_GRID:"MOD10A1_multiband_HEGOUT.hdf":MOD_Grid_Snow_500m_16:NDSI
SUBDATASET_4_DESC=[350x831] NDSI MOD_Grid_Snow_500m_16 (16-bit integer)
SUBDATASET_5_NAME=HDF4_EOS:EOS_GRID:"MOD10A1_multiband_HEGOUT.hdf":MOD_Grid_Snow_500m_16:Snow_Albedo_Daily_Tile
SUBDATASET_5_DESC=[350x831] Snow_Albedo_Daily_Tile MOD_Grid_Snow_500m_16 (8-bit unsigned integer)
SUBDATASET_6_NAME=HDF4_EOS:EOS_GRID:"MOD10A1_multiband_HEGOUT.hdf":MOD_Grid_Snow_500m_16:orbit_pnt
SUBDATASET_6_DESC=[350x831] orbit_pnt MOD_Grid_Snow_500m_16 (8-bit integer)
SUBDATASET_7_NAME=HDF4_EOS:EOS_GRID:"MOD10A1_multiband_HEGOUT.hdf":MOD_Grid_Snow_500m_16:granule_pnt
SUBDATASET_7_DESC=[350x831] granule_pnt MOD_Grid_Snow_500m_16 (8-bit unsigned integer)
现在,您可以打开任何将子数据集的 GDAL 完全限定名称作为参数传递的子数据集。例如:
rasterio.open('HDF4_EOS:EOS_GRID:"MOD10A1_multiband_HEGOUT.hdf":MOD_Grid_Snow_500m_16:NDSI_Snow_Cover')
编辑:我根据作者的建议添加了外部单引号。