xarray 如何使用 open_rasterio 加载和索引大型 GeoTIFF 文件?

How does xarray load and index large GeoTIFF files with open_rasterio?

我正在使用 xarray 包来加载和访问大型 GeoTIFF 文件 (>50GB) 的数据,它工作得很好。

import xarray as xr
img = xr.open_rasterio("path/to/large_geo_tiff.tif")
pixel_value = img[0,1225, 4321]
print("The pixel value is: ", pixel_value.values.item())

但是,我想知道 xarray 实际上是如何加载大型 GeoTIFF 文件的。显然它不会将整个文件加载到内存中,因为它不适合而是执行某种延迟加载。我只习惯 daskDask Arrays ,它们将数据分成块,并通过将相应的块加载到记忆。 但是函数的签名 open_rasterio 看起来像下面这样

xarray.open_rasterio(filename, parse_coordinates=None, chunks=None, cache=None, lock=None)

因为我没有定义 chunks 所以 img 不应该被分块。所以我的问题是调用 pixel_value = img[0,1225, 4321] 时会发生什么,xarray 如何快速访问给定位置的像素值?

我期待任何反馈。

xarray 相比,dask_image 似乎在读取 tiff 文件 时并不聪明

提供的 GeoTIFF 不是 tiled 但我刚刚检查了 tiff 文件格式如下所示

TIFF File: '/Users/jan/Desktop/ms-project/processed/metashape/export/untiled.tif'
                       Mode: 'r'
    Current Image Directory: 1
           Number Of Strips: 1336
                SubFileType: Tiff.SubFileType.Default
                Photometric: Tiff.Photometric.RGB
                ImageLength: 42746
                 ImageWidth: 35366
               RowsPerStrip: 32
              BitsPerSample: 8
                Compression: Tiff.Compression.LZW
               SampleFormat: Tiff.SampleFormat.UInt
            SamplesPerPixel: 3
        PlanarConfiguration: Tiff.PlanarConfiguration.Chunky
                Orientation: Tiff.Orientation.TopLeft

重要的部分是 tifstripped,其中每个条带都是连续行的单独集合使随机访问更容易的位图图像数据和 xarray 似乎通过加载所需数据来利用 stripped 图像 - 我刚刚检查了这个通过加载 GeoTIFF 调用 xarray.open_rasterio 使用的后端模块调用 rasterio

>>> import rasterio
>>> ortho = rasterio.open("./orthomosaic.tif")
>>> ortho.is_tiled
False
>>> ortho.block_shapes
[(32, 248489), (32, 248489), (32, 248489)]
另一方面,

dask_image 没有利用这些条纹,而是将整个图像加载到一个 chunk 中运行 out out memory - 即使你写一个tiledtif文件dask_image也不会考虑这个

>>> import dask_image.imread
>>> ortho = dask_image.imread.imread("./orthomosaic.tif")
>>> ortho
dask.array<from-value, shape=(1, 104700, 248489, 3), dtype=uint8, chunksize=(1, 104700, 248489, 3), chunktype=numpy.ndarray>