如何用Python Boto3从S3下载指定经纬度范围的Sentinel影像?
按经纬度范围裁剪下载Sentinel S3影像(支持请求付费)
当然可以实现!直接用boto3本身没法对影像进行空间裁剪,不过我们可以结合GDAL的Python绑定和支持请求付费的S3访问方式,完美解决你的需求——既不用下载完整文件,又能适配S3的RequestPayer规则。
为什么之前的gdal_translate命令失效?
你之前用/vsicurl/http://...的方式访问S3,这种HTTP方式没法传递RequestPayer参数,所以遇到启用了请求付费的Bucket就会报错。GDAL从2.3版本开始支持/vsis3/虚拟文件系统,它可以直接调用AWS SDK(依赖boto3的配置),并且能传递请求付费的参数。
解决方案:Python结合GDAL + S3请求付费配置
1. 先确保安装依赖
需要安装GDAL的Python包和boto3:
pip install gdal boto3
注意:GDAL版本建议2.3以上,确保支持
AWS_REQUEST_PAYER参数。
2. 完整Python代码示例
下面的代码会直接从S3裁剪指定经纬度范围的影像并保存到本地,同时带上请求付费参数:
from osgeo import gdal import os # 配置GDAL的S3请求付费参数 gdal.SetConfigOption('AWS_REQUEST_PAYER', 'requester') # 可选:设置临时目录,处理大文件时避免内存溢出 gdal.SetConfigOption('CPL_TMPDIR', './temp') # S3 Bucket和文件路径 bucket_name = 'sentinel-s2-l1c' s3_key = 'tiles/7/W/FR/2018/3/31/0/B8A.jp2' # 构建GDAL的S3虚拟文件路径 s3_vsi_path = f'/vsis3/{bucket_name}/{s3_key}' # 你的裁剪范围:格式为 [ulx, uly, lrx, lry],对应WGS84的(经度最小, 纬度最大, 经度最大, 纬度最小) projwin = [23.22, 80.32, 23.55, 80.44] output_path = './B8A_cropped.jp2' # 执行裁剪 ds = gdal.Translate( destName=output_path, srcDS=s3_vsi_path, projwin=projwin, projwin_srs='EPSG:4326', format='JP2OpenJPEG' # 保持原格式,也可以换成其他格式比如GTiff ) # 释放资源 ds = None print(f"裁剪后的影像已保存到: {output_path}")
关键说明
- S3路径格式:用
/vsis3/[bucket]/[key]代替HTTP URL,GDAL会自动通过boto3的配置访问S3,同时带上RequestPayer参数。 - 裁剪范围参数:
projwin的顺序是左上角经度、左上角纬度、右下角经度、右下角纬度,对应你提到的longMin, latMax, longMax, latMin,注意别搞反顺序! - GDAL配置:
AWS_REQUEST_PAYER必须设置为'requester',否则访问请求付费Bucket会被拒绝。 - 身份验证:GDAL会自动读取boto3的配置(比如环境变量、
~/.aws/credentials文件),确保你的AWS密钥有访问该S3 Bucket的权限。
替代思路:如果不想用GDAL?
如果必须只用boto3,那只能先下载完整文件,再用其他Python影像库(比如rasterio)裁剪,但这样会浪费带宽和存储空间,显然不如直接用GDAL的虚拟文件系统高效。
内容的提问来源于stack exchange,提问作者gaurav singh
相关产品推荐
相关产品推荐

