使用Python的boto3从S3下载Sentinel文件

3
我正在使用以下代码从S3下载完整大小的Sentinel文件。
import boto3

s3_client = boto3.Session().client('s3')
response = s3_client.get_object(Bucket='sentinel-s2-l1c',
                        Key='tiles/7/W/FR/2018/3/31/0/B8A.jp2', 
                        RequestPayer='requester')
response_content = response['Body'].read()

with open('./B8A.jp2', 'wb') as file:
     file.write(response_content)

但我不想下载完整尺寸的图片。有没有一种基于latMax、longMin、LatMin和LatMax下载图像的方法呢?我之前使用了下面的命令,但由于数据在S3上被设置为请求者付费,所以它无法工作。

gdal_translate --config CPL_TMPDIR temp -projwin_srs "EPSG:4326" -projwin 23.55 80.32 23.22 80.44 /vsicurl/http://sentinel-s2-l1c.s3-website.eu-central-1.amazonaws.com/tiles/43/R/EQ/2020/7/26/0/B02.jp2 /TestScript/B02.jp2

有没有办法使用Python boto来实现这个功能?
1个回答

3
您可以使用rasterio访问图像的子窗口:
(我假设 AWS 凭据已经设置用于与boto3一起使用,并且您具有必要的权限)
import boto3
from matplotlib.pyplot import imshow
import rasterio as rio
from rasterio.session import AWSSession
from rasterio.windows import Window

# create AWS session object
aws_session = AWSSession(boto3.Session(), requester_pays=True)

with rio.Env(aws_session):
    with rio.open("s3://sentinel-s2-l1c/tiles/7/W/FR/2018/3/31/0/B8A.jp2") as src:
        profile = src.profile
        win = Window(0, 0, 1024, 1024)
        arr = src.read(1, window=win)

imshow(arr)

raster plot

print(arr.shape)

(1024, 1024)

解释:

如果AWS凭证已经正确配置给boto3,则可以基于boto3.Session()创建一个AWSSession对象。这样将会为S3访问设置必要的凭证。添加标记requester_pays=True以便从请求方支付的存储桶中读取。

AWSSession对象可以传递到rasterio.Env上下文中,使得rasterio(更重要的是底层的gdal函数)可以访问这些凭证。

使用rasterio.windows.Window将任意子窗口(0, 0, 1024, 1024)读取到内存中,但您也可以按照文档中所述,使用坐标定义窗口。

从此,您可以处理数组或将其保存到磁盘中。


抱歉,我已经阅读了整个文档,但仍然无法找到基于纬度和经度的window()函数。 - gaurav singh
还有没有办法根据纬度和经度找出col_off和row_off的值? - gaurav singh
你需要将你的坐标转换到 S2 投影中,这样你就可以使用 rasterio.windows.from_bounds - 关于点重投影方面有很多文档:例如 这个这个 或者 那个 - Val
在这种情况下,我必须下载完整大小的JP2文件,然后重新投影它,然后使用纬度和经度。 - gaurav singh
如果您的兴趣区域不在投影坐标系中,而是在地理坐标系中,您可以尝试重新投影这些坐标,以创建地图坐标系下的边界框。然后,可以使用此边界框仅访问所需区域。不必下载和/或重新投影整个图像。 - Val

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接