基于 python sentinelsat 包的Sentinel-2数据下载(LongTermArchive)


动机

Google earth engine 虽然解决了很多数据下载的问题,使数据的下载和处理变的快捷,但是如果想深入了解任何卫星的数据及信息,我个人感觉还是需要下载下来看一看。不为别的,就当涨涨眼界,如果博士毕业,连Sentinel、Modis等基本原始数据都没用过、处理过,有点丢人。尤其是如果公司或者研究所需要完全独立的做一个数据生产的系统,要求数据的实时性,那就不能嫁接Google earth engine的基功能了。我个人认为多涉猎还是非常有必要的。写此博客,留做笔记。 以此为出发点,并依据相关项目及老师的需求,写了此代码,基于 sentinelsat 的Sentinel-2数据下载。解决了 LongTermArchive 下载的问题。

提示:以下是本篇文章正文内容,案例可供参考

正文

参考了很多网上的帖子,包括 知乎 和 CSDN,一直没找到解决 LongTermArchive 半个小时访问一次的问题,代码跑着跑着就断了,很头疼。
最终,仔细研读 sentinelsat 官方文档 https://sentinelsat.readthedocs.io/en/latest/api_overview.html#opensearch-example,明白了怎么回事,然后在官方示例上进行了修改。完成了任务。

还有人在帖子中 'https://apihub.copernicus.eu/apihub' 写成了 'https://scihub.copernicus.eu/apihub/',不知道是不是两个网站都可以,但是我的后者是下载不下来的。

代码里面都有注释,不明白的自己看。再有问题,就可以直接联系我了。尤其是我希望能有会 CESM或者CLM的小伙伴帮帮我。

#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
@version: Anaconda
@author: LeYongkang
@contact: 1363989042@qq.com
@software: PyCharm
@file: Sentinel_Download
@time: 2021/9/04 0020 下午 9:23
参考文档:http://www.acgeospatial.co.uk/sentinelsat_demo/
"""
from sentinelsat import SentinelAPI, read_geojson, geojson_to_wkt
from datetime import date
import time
import datetime
import os

def download_sentinel_data(user_name,password,website,foot_print,start_date,end_date,platformname,max_cloud):

    print("进入函数")

    download_dir = "./sentinel-2"

    # 判断下载文件夹在不在,如果不在,自动建立子目录
    if not os.path.exists(download_dir):
        os.makedirs(download_dir)

    api = SentinelAPI(user_name,password,website)
    products = api.query(
                     foot_print,
                     date=(start_date, end_date),
                     platformname=platformname, # 可选: Sentinel-1,Sentinel-2,Sentinel-3,Sentinel-5 Precursor
                     producttype = 'S2MSI2A',   # Sentinel-2 可选: S2MSI2A,S2MSI1C, S2MS2Ap
                     cloudcoverpercentage = (0, max_cloud)
    )

    print(len(products))

    while True:
        for product in products:
            product_info = api.get_product_odata(product)
            # print(product_info)
            # 获取文件 id ,通过 id 号下载文件
            product_id = product_info['id']
            # 获取文件 title,title + .zip 为完整的文件名
            product_title = product_info['title']
            print("{}".format(product_id))
            print("{}".format(product_title))

            product_info = api.get_product_odata(product_id)
            is_online = product_info['Online']

            # 判断是否在线
            if is_online:   # 如果在线,执行
                print('编号为 {} 的产品在线。'.format(product_id))
                if not os.path.isfile(download_dir + os.sep + product_title + ".zip"):   # 单账号的时候使用
                    print('本地无 {}.zip 的完整文件。'.format(product_title))
                    # if not os.path.isfile( download_dir + os.sep + product_title + ".zip.incomplete" ):  # 双账号的时候
                    # print('本地无 {}.zip.incomplete 的未完成文件。开始下载'.format(product_title))
                    # 注意:上次下载一半,下次重启代码,循环到上次下载的文件时,会继续下载(接着.zip.incomplete继续下载)
                    api.download(product_id,directory_path= download_dir)

            else:   # 如果不在线,需要触发一次,然后跳过,(出发后,会在半小时后转化为在线)等待后续再下载
                print('编号为 {} 的产品不在线。'.format(product_id))

                if not os.path.isfile(download_dir + os.sep + product_title + ".zip"):  # 单账号的时候使用
                    print('本地无 {}.zip 的完整文件,尝试触发 LongTermArchive 库'.format(product_title))

                    try: # 尝试触发
                        api.download(product_info['id'], directory_path= download_dir)
                        api.trigger_offline_retrieval(product_id)
                        break  # if successful, move past
                    except Exception as e:
                        print("[ERROR] Request failed.. sleeping for 31 mins before retrying (current time: {})".format(
                            datetime.datetime.now()))
                        #     time.sleep(60 * 31)

        # 离线的 每 30 min 才能提交一次请求
        time.sleep(60 * 31)



if __name__ == '__main__':
    # 有时候单个账号访问次数多了,会限制访问,大约办个小时后解禁;限制访问的时候,可以使用另一个账号
    # user_name="username"
    # password = "password"

    user_name="username"
    password = "password"

    website = 'https://apihub.copernicus.eu/apihub'
    # map.geojson 限制了下载数据的范围
    # 来 https://geojson.io/#map=2/20.0/0.0 网站,自己画个区域就行;然后 copy 到 map.geojson里面就可以
    foot_print = geojson_to_wkt(read_geojson(r'./map.geojson'))

    start_date = '20210813'
    end_date = date(2021, 9, 13)  # 这样的 2021-09-13 格式
    print(end_date)
    # 下载的数据类型
    platformname = 'Sentinel-2'
    # 控制云量最大值
    max_cloud = 30
    # print("test")
    download_sentinel_data(user_name, password, website, foot_print, start_date, end_date, platformname,max_cloud)

结语

慢慢积累,不知不觉我的博客已经18个了,这个时第19个。

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值