我正在尝试找到将 dask 数组保存到 geotiff 的最佳/最快方法。
我一直在研究如何使 rasterio/GDAL 线程安全,但我没有想出任何可以从python轻松访问的东西。
如果我使用da.store(..., lock=False)
,那么文件可能会损坏。我尝试为每次写入打开和关闭文件,但这仍然使用相同的文件描述符(如果我错了,请纠正我)并且无论如何都不是一个很好的解决方案。
有没有人有另一种方法来做到这一点,以便每个 dask 工作人员(线程)可以安全地写入由rasterio库创建的geotiff文件?当前的工作解决方案是保留其默认值.dask.store
lock-True
我猜任何其他解决方案无论如何都会涉及线程锁定,但我认为无论如何在这里有这个解决方案会很好。
我的工作示例代码如下:
import dask.array as da
import numpy as np
import rasterio
from rasterio.windows import Window
class RIOFile(object):
"""Rasterio wrapper to allow da.store to do window saving."""
def __init__(self, *args, **kwargs):
"""Initialize the object."""
self.args = args
self.kwargs = kwargs
self.rfile = None
def __setitem__(self, key, item):
"""Put the data chunk in the image."""
if len(key) == 3:
indexes = list(range(
key[0].start + 1,
key[0].stop + 1,
key[0].step or 1
))
y = key[1]
x = key[2]
else:
indexes = 1
y = key[0]
x = key[1]
chy_off = y.start
chy = y.stop - y.start
chx_off = x.start
chx = x.stop - x.start
# band indexes
self.rfile.write(item, window=Window(chx_off, chy_off, chx, chy),
indexes=indexes)
def __enter__(self):
"""Enter method."""
self.rfile = rasterio.open(*self.args, **self.kwargs)
return self
def __exit__(self, exc_type, exc_value, traceback):
"""Exit method."""
self.rfile.close()
rows = cols = 21696
a = da.ones((4, rows, cols), dtype=np.float64, chunks=(1, 4096, 4096) )
a = a * np.array([255., 255., 255., 255.])[:, None, None]
a = a.astype(np.uint8)
with RIOFile('test.tif', 'w', driver='GTiff', width=cols, height=rows, count=4, dtype=np.uint8) as r_file:
da.store(a, r_file, lock=True)
更改lock=False
可能损坏的文件。
我也能够通过增加 GDAL 的内部缓存大小来获得成功的输出,尽管不能保证。