GDAL:写入 zip 存档
GDAL: write to zip archive
我知道从 2.2 版开始,gdal
有虚拟文件系统驱动程序,例如 /vsizip/
用于访问 zip
档案。
以前我已经能够从 zip
档案中读取,但我无法写信给他们(我想这也应该是可能的)。我也没有找到太多关于这个的文档。
这是我试过的:
import gdal
from zipfile import ZipFile
import numpy as np
with ZipFile('test.zip','a') as zfile:
driver = gdal.GetDriverByName('GTiff')
raster = driver.Create('/vsizip/test.zip/testraster.tif',10,10, 1, gdal.GDT_Float32)
raster.GetRasterBand(1).writeArray(np.random.random(10,10))
raster = None
但我总是收到
AttributeError: 'NoneType' object has no attribute 'GetRasterBand'
编辑:
根据 Gabriella Giordano 的建议更新了片段。
编辑 2:
Gabriella 指出 GTiff
驱动程序需要同时读取和写入访问权限,这是(目前?)不支持的。
建议的解决方法是创建一个临时文件,然后将其复制到存档中。
我真的很想直接在存档中创建光栅文件(不必是 tiff)。如果我想复制它们,我还不如使用zipfile
之类的
有什么想法吗?
编辑 3:
完全公开*,这就是我要实现的目标:
我有 MODIS hdf
文件,我想直接将值栅格子数据集保存到 zip 存档中。
解决方案:
借助加布里埃拉 (Gabriella) 的出色洞察力,我终于做到了。
我最终使用 gdal.Translate
并将其传递给 options
:
gdal.TranslateOptions(creationOptions=['STREAMABLE_OUTPUT=TRUE'])
*我认为这不是相关信息,但 Gabriela 的回答让我觉得是。
我不是很流利 python,但数据集创建可能失败了,因为您没有设置波段数。
试试这个:
raster = driver.Create('/vsizip/test.zip/testraster.tif',10,10, 1, gdal.GDT_Float32)
将 1 更改为所需的波段数。
您可以找到 Create here 的完整参数列表。
编辑:
找到问题的可能原因(以及可能的解决方法)here. As reported at this link,显然 Create 的打开模式与 vsizip 虚拟文件系统不兼容。
编辑 2
这不是您使用的驱动程序(例如GeoTiff)的问题,而是虚拟文件系统本身的问题。
Create 调用尝试以两种 read/write 模式打开文件,因为 GDAL 出于性能原因将文件系统用作缓存,而不仅仅是为了存储。但在这种情况下,虚拟 vsizip 文件系统不允许同时读取和写入文件,因为它不支持随机访问。
vsizip vfs 确实提供了独立的即时读取和写入,因为它 compress/decompress 在后台为您提供数据。这意味着您不能来回跳转(如在 read/write 打开模式请求的随机访问模式中),因为您在磁盘上写入的内容(压缩数据)与您最终可以读取的内容(未压缩数据)不同。
编辑 3
我发现 gdal 命令行工具(如 gdal_translate 或 gdal_warp)在使用时自动设置 'STREAMABLE_OUTPUT = TRUE' 虚拟文件系统。可流文件格式强制执行应符合非随机访问文件系统的只写策略。您可以将此选项设置为 Create 调用的附加参数。同样,我有限的 python 能力使我无法提供工作片段。
不过请考虑,steamable 也意味着对您可以在数据集上执行的操作类型有一些限制,因此这可能无法解决您的问题,但是无论如何知道是有用的...
我知道从 2.2 版开始,gdal
有虚拟文件系统驱动程序,例如 /vsizip/
用于访问 zip
档案。
以前我已经能够从 zip
档案中读取,但我无法写信给他们(我想这也应该是可能的)。我也没有找到太多关于这个的文档。
这是我试过的:
import gdal
from zipfile import ZipFile
import numpy as np
with ZipFile('test.zip','a') as zfile:
driver = gdal.GetDriverByName('GTiff')
raster = driver.Create('/vsizip/test.zip/testraster.tif',10,10, 1, gdal.GDT_Float32)
raster.GetRasterBand(1).writeArray(np.random.random(10,10))
raster = None
但我总是收到
AttributeError: 'NoneType' object has no attribute 'GetRasterBand'
编辑:
根据 Gabriella Giordano 的建议更新了片段。
编辑 2:
Gabriella 指出 GTiff
驱动程序需要同时读取和写入访问权限,这是(目前?)不支持的。
建议的解决方法是创建一个临时文件,然后将其复制到存档中。
我真的很想直接在存档中创建光栅文件(不必是 tiff)。如果我想复制它们,我还不如使用zipfile
之类的
有什么想法吗?
编辑 3:
完全公开*,这就是我要实现的目标:
我有 MODIS hdf
文件,我想直接将值栅格子数据集保存到 zip 存档中。
解决方案:
借助加布里埃拉 (Gabriella) 的出色洞察力,我终于做到了。
我最终使用 gdal.Translate
并将其传递给 options
:
gdal.TranslateOptions(creationOptions=['STREAMABLE_OUTPUT=TRUE'])
*我认为这不是相关信息,但 Gabriela 的回答让我觉得是。
我不是很流利 python,但数据集创建可能失败了,因为您没有设置波段数。
试试这个:
raster = driver.Create('/vsizip/test.zip/testraster.tif',10,10, 1, gdal.GDT_Float32)
将 1 更改为所需的波段数。
您可以找到 Create here 的完整参数列表。
编辑:
找到问题的可能原因(以及可能的解决方法)here. As reported at this link,显然 Create 的打开模式与 vsizip 虚拟文件系统不兼容。
编辑 2
这不是您使用的驱动程序(例如GeoTiff)的问题,而是虚拟文件系统本身的问题。 Create 调用尝试以两种 read/write 模式打开文件,因为 GDAL 出于性能原因将文件系统用作缓存,而不仅仅是为了存储。但在这种情况下,虚拟 vsizip 文件系统不允许同时读取和写入文件,因为它不支持随机访问。
vsizip vfs 确实提供了独立的即时读取和写入,因为它 compress/decompress 在后台为您提供数据。这意味着您不能来回跳转(如在 read/write 打开模式请求的随机访问模式中),因为您在磁盘上写入的内容(压缩数据)与您最终可以读取的内容(未压缩数据)不同。
编辑 3
我发现 gdal 命令行工具(如 gdal_translate 或 gdal_warp)在使用时自动设置 'STREAMABLE_OUTPUT = TRUE' 虚拟文件系统。可流文件格式强制执行应符合非随机访问文件系统的只写策略。您可以将此选项设置为 Create 调用的附加参数。同样,我有限的 python 能力使我无法提供工作片段。
不过请考虑,steamable 也意味着对您可以在数据集上执行的操作类型有一些限制,因此这可能无法解决您的问题,但是无论如何知道是有用的...