如何使用VSIS3从S3存储桶中通过GDAL有效地访问文件?


19

因此,GDAL最近添加了一项新功能,该功能允许随机读取S3存储桶文件。我希望从图像的多个图块中裁剪GDAL图像,而不必下载整个文件。我只看过关于如何通过GDAL配置和访问S3存储桶的非常稀疏的文档,并且对如何开始感到困惑。是否有人会提供一个非常简短的示例/教程来说明如何为GDAL设置虚拟文件系统以实现这一目标?如果您的解决方案允许通过Python编写脚本,请加分!

需要说明的是:我们已经用Python完成了它。Python的问题在于,您必须下载整个图像才能对其进行操作。GDAL的最新版本支持安装S3存储桶,因此,如果我们需要对图像的一小部分进行裁剪,则可以直接在该小部分上进行操作。las,该功能仅在一月份在稳定分支中发布,因此我没有找到任何文档。因此,该解决方案应使用GDAL的最新版本中的VSI3系统,否则应巧妙地使用该系统,以防止用户需要将整个映像下载到EBS驱动器上以对其进行操作。

也就是说,悬赏将授予使用最新版本GDAL中的VSI API的答案,从而无需将整个文件读取到内存或磁盘中。另外,我们使用的存储桶并不总是公开的,因此发布的许多HTTP技巧在我们的许多情况下都行不通。



没有使用S3 / bucket的经验,但可能对此文章感兴趣:link。类似使用(?)
cm1

@ cm1谢谢您,该文档到目前为止是最好的帮助。
Skylion '16

很高兴听见。我认为这是您提出的一个很好的问题,我正在密切关注。希望您/其他人解决并在此处发布一个不错的解决方案!
2016年

Answers:


18

我发现当GDAL中没有特别好的文档记录时,仔细检查他们的测试会很有用。

/vsis3测试模块有一些简单的例子,虽然它并没有实际读取的块的任何实例。

我已根据测试模块将下面的代码拼凑在一起,但是由于GDAL / vsis3需要凭证且我没有AWS账户,因此无法进行测试。

"""This should read from the Sentinal-2 public dataset
   More info - http://sentinel-pds.s3-website.eu-central-1.amazonaws.com"""

from osgeo import gdal
import numpy as np

# These only need to be set if they're not already in the environment,
# ~/.aws/config, or you're running on an EC2 instance with an IAM role.
gdal.SetConfigOption('AWS_REGION', 'eu-central-1')
gdal.SetConfigOption('AWS_SECRET_ACCESS_KEY', 'MY_AWS_SECRET_ACCESS_KEY')
gdal.SetConfigOption('AWS_ACCESS_KEY_ID', 'MY_AWS_ACCESS_KEY_ID')
gdal.SetConfigOption('AWS_SESSION_TOKEN', 'MY_AWS_SESSION_TOKEN')

# 'sentinel-pds' is the S3 bucket name
path = '/vsis3/sentinel-pds/tiles/10/S/DG/2015/12/7/0/B01.jp2'
ds = gdal.Open(path)

band = ds.GetRasterBand(1)

xoff, yoff, xcount, ycount = (0, 0, 10, 10)
np_array = band.ReadAsArray(xoff, yoff, xcount, ycount)

2
呜呜声就像魅力!这是来自命令行btw的裁剪示例:gdal_translate --config AWS_REGION“ some_region” --config AWS_ACCESS_KEY_ID“ KEY_ID” --config AWS_SECRET_ACCESS_KEY“ ACCESS_KEY” \ -srcwin 000 000 1000 1000 \“ /vsis3/bucket/file.ext” from_s3.tif
Skylion '16

您隐藏的那些值是什么样的?我认为KEY_ID是一个简短的文本字符串,例如用户名。什么是ACCESS_KEY?似乎是pem文件中的内容,但是大约1000个字符,因此它必须是其他内容。
Solx

这些只是带有数字和字母的字符串,有点像用户名和密码。您可以通过在AWS中设置IAM角色来获取这些字符串
RutgerH

10

由于/vsis3/是在GDAL中实现的,因此您还可以rasterio用来读取S3数据集的Windows。这要求你的信任而设立博托或使用rasterios AWS会话处理程序

import rasterio

with rasterio.open('s3://landsat-pds/L8/139/045/LC81390452014295LGN00/LC81390452014295LGN00_B1.TIF') as ds:
    window = ds.read(window=((0, 100), (0, 100)))  # read a 100 by 100 window in the upper left corner.

另请参见rasterios windowed-rwVSI文档。


1

尝试使用XML文件存储WMS信息,有关更多详细信息,请参见GDAL WMS文档

这是一个示例WMS XML文件,用于从Mapzen的Elevation API中检索数据:

<GDAL_WMS>
  <Service name="TMS">
    <ServerUrl>https://s3.amazonaws.com/elevation-tiles-prod/geotiff/${z}/${x}/${y}.tif</ServerUrl>
  </Service>
  <DataWindow>
    <UpperLeftX>-20037508.34</UpperLeftX>
    <UpperLeftY>20037508.34</UpperLeftY>
    <LowerRightX>20037508.34</LowerRightX>
    <LowerRightY>-20037508.34</LowerRightY>
    <TileLevel>14</TileLevel>
    <TileCountX>1</TileCountX>
    <TileCountY>1</TileCountY>
    <YOrigin>top</YOrigin>
  </DataWindow>
  <Projection>EPSG:3857</Projection>
  <BlockSizeX>512</BlockSizeX>
  <BlockSizeY>512</BlockSizeY>
  <BandsCount>1</BandsCount>
  <DataType>Int16</DataType>
  <ZeroBlockHttpCodes>403,404</ZeroBlockHttpCodes>
  <DataValues>
    <NoData>-32768</NoData>
  </DataValues>
  <Cache/>
</GDAL_WMS>

然后,您可以像这样裁剪到边界框:

gdalwarp -of "GTiff" -te -13648825.0817 4552130.7825 -13627575.5878 4565507.2624 mapzen_wms.xml test.tif

尽管这是一个有用的答案,但是我们已经以类似的方式缓存了元数据,但是我们想知道如何使用VSI API,以便可以快速裁剪大图像的一小部分。
Skylion '16

我不确定这是否是因为Mapzen API端点是平铺的WMS,但是上面的代码在一分钟内为我运行了,您确定VSI API会更快吗?
clhenrick '16

我们正在使用非常大的栅格和大型栅格数据集,瓶颈肯定是IO。同样,我们使用的存储桶是私有的,并且需要凭据,这意味着在我们的情况下无法使用S3 http API。不是我们必须阅读每张图像,而是我们知道我们必须废除非常大图像的一小部分。
Skylion '16

0

我对S3存储桶了解不多,但似乎是使用http REST服务进行身份验证的云存储驱动器。即可以用作带有相关uri的普通安装点。

如果您正在寻找图像/光栅的一部分,则文件必须采用适当的格式。

看一下TMS规范 http://wiki.osgeo.org/wiki/Tile_Map_Service_Specification

(也许netCDF也可以解决问题。)

GDAL还读取和写入TMS格式。基本上,它只是带有一些元数据文件的标准目录结构。

现在,诀窍是通过TMS驱动程序动态创建带有地理范围参数的url。

看一下OpenLayers TMS驱动程序文档:http : //dev.openlayers.org/docs/files/OpenLayers/Layer/TMS-js.html 要了解它如何根据位置,缩放和范围来处理请求。

当然可以用Python完成。您首先需要使用viscurl(根据文档)创建适当的“安装点”(或路径)URI,然后根据TMS规范将其安装到特定磁贴上(这是路径的扩展) 。


我只是添加了一些说明,以区别于仅在Python中使用S3接口。
Skylion
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.