文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

【Python&RS】基于Python批量下载哨兵二号数据

2023-10-11 21:42

关注

        学遥感的避免不了使用哨兵数据,毕竟10m的分辨率可以满足大部分的定量分析,同时也是最重要的一点,它免费!!!

        但如果一幅一幅去下载影像实在是太慢了,特别是如果需要研究长时间序列的影像,那下载数据就成了最痛苦的环节了。所以这里给大家分享一下如何使用Python和IDM批量下载哨兵二号数据,当然欧空局的其他数据也可以下载。

        这里说明一下,IDM下载的代码部分参考了一些博主的代码,但我找不到他们了(泪目)。如果有所冒犯,请联系作者删除。

一、注册账号

        想要下载数据,你总归需要一个账号吧!欧空局官网,点击左上角login注册一个账号先。

二、制作兴趣区范围

        我们在查找数据时一般都需要一个研究区,如一个省或者一个市,那么就需要研究区的矢量文件去限制我们查找数据的范围。这里需要使用一个导出GeoJSON的工具,先画出研究区再导出GeoJSON即可。

三、查找数据

        欧空局发布过一个Python的包sentinelsat,大家有兴趣可以自己看看文档,通过这个包我们可以通过日期、云量、范围、卫星类型等查询我们需要的影像数据。

        代码中的注释比较详细,所以我就不过多介绍了。

def Search_data(login, key, path_geojson, start_date, end_date, name, product_type, cloud, filepath):    """    :param login: 欧空局账号,字符串类型    :param key: 欧空局密码,字符串类型    :param path_geojson: 兴趣区路径及文件名    :param start_date: 开始时间,字符串    :param end_date: 结束时间,字符串    :param name: 卫星名称    :param product_type: 卫星类型    :param cloud: 云量筛选,格式:(0,15)    :param filepath: Url保存路径及文件名    :return: 返回存有下载链接的excel路径    """    api = SentinelAPI(login, key, 'https://scihub.copernicus.eu/dhus')    # 登陆账号https://scihub.copernicus.eu/apihub/    footprint = geojson_to_wkt(read_geojson(path_geojson))    # 读取兴趣区,兴趣区由http://geojson.io导出    products = api.query(footprint,                         date=(start_date, end_date),  # 搜索的日期范围                         platformname=name,   # 卫星平台名,Sentinel-2                         producttype=product_type,  # 产品数据等级,Sentinel-2: S2MSI2A,S2MSI1C,S2MS2Ap/Sentinel-1:SLC,GRD,OCN                         cloudcoverpercentage=cloud)  # 云量百分比    # 搜索A、B双星的数据    row = 0    workbook_write = xlwt.Workbook(encoding='utf-8')    worksheet_write = workbook_write.add_sheet('Url_image')    for product in products:        # 通过for循环遍历并打印、下载出搜索到的产品文件名        info_product = api.get_product_odata(product)        # 通过OData API获取单一产品数据的主要元数据信息        worksheet_write.write(row, 0, info_product['url'])        worksheet_write.write(row, 1, info_product['title'])        print(info_product['title'])        # print(product_info['url'])        # 打印下载的产品数据文件名,id/uuid代码编号,size数据大小,title,url链接,md5,date时间        # api.download(product)        row += 1    workbook_write.save(filepath)    return filepath, api    # 循环结束后,保存表格

四、调用IDM批量下载

        这里读取之前保存的下载链接的表格,再调用IDM批量对链接进行下载。哨兵数据有些是offline的,不能直接下载。但官方给出了激活函数,可以通过该函数对数据进行激活后就可以下载了。

def Download_image(filepath, Path_Download, Path_IDM, api):    workbook_read = xlrd2.open_workbook(filepath)    # 打开表格,创建工作空间    sheet1 = workbook_read.sheet_by_name('Url_image')    # 选择需要读取的sheet    link_list = sheet1.col_values(0)    # 获取第一列的数据    print('所有链接下载完成,现在开始下载对应数据')    num = 0    while link_list:        print('---------------------------------------------------')        num += 1        print('\n')        print('第' + str(num) + '次循环' + '\n')        id = link_list[0].split('\'')[1]        link = link_list[0]        info_product = api.get_product_odata(id)        print('查询当前列表里的第一个数据的状态')        if info_product['Online']:            print(info_product['title'] + '为:online产品')            print('加入IDM的下载列表中: ')            print('\n')            call([Path_IDM, '/d', link, '/p', Path_Download, '/n', '/a'])            link_list.remove(link)            call([Path_IDM, '/s'])        else:            print(info_product['title'] + '为:offline产品')            print('\n')            print('激活offline产品')            code_id = link_list[0].split('\'')[1]            api.trigger_offline_retrieval(code_id)            # 激活offline产品            print('检查任务列表里是否存在online产品: .........')            # 等待激活成功的时候,检查现在的列表里还有没有online产品            # 如果有online的产品那就下载            # 首先检查列表中是否需要下载的数据            if len(link_list) > 1:                # 记录列表里可以下载的链接,并在最后把它们删除                link_list_1 = []                # 开始寻找列表剩下的元素是否有online产品                for i in range(1, len(link_list)):                    id2 = link_list[i].split('\'')[1]                    link_1 = link_list[i]                    info_product2 = api.get_product_odata(id2)                    if info_product2['Online']:                        print(info_product2['title'] + '为Online产品')                        print('加入IDM的下载列表中: ')                        print('--------------------------------------------')                        call([Path_IDM, '/d', link_1, '/p', Path_Download, '/n', '/a'])                        # 在列表中加入需要删除产品的HTTP链接信息                        # 直接在link_list中删除会link_list的长度会发生改变,最终造成i的值超过link_list的长度                        link_list_1.append(link_1)                    else:                        continue                # 把已经下载的数据的链接给删除掉                if len(link_list_1) > 0:                    call([Path_IDM, '/s'])                    for link_2 in link_list_1:                        link_list.remove(link_2)            print('本轮次检查结束,开始等到40分钟')            # 将该激活的产品删除,再加入到最后            link_list.remove(link)            link_list.append(link)            # 两次激活offline数据的间隔要大于30分钟            for i in tqdm(range(int(1200)), ncols=100):                time.sleep(2)

五、完整代码

# -*- coding: utf-8 -*-"""@Time : 2023/3/31 15:35@Auth : RS迷途小书童@File :Batch download of Sentinel data.py@IDE :PyCharm@Purpose :批量下载哨兵数据"""from sentinelsat import SentinelAPI, read_geojson, geojson_to_wkt# 导入用户登录,兴趣区识别模块from subprocess import call# 用来唤醒IDM下载数据from datetime import dateimport timeimport xlwtimport xlrd2# excel的读取和写入模块from tqdm import tqdmdef Search_data(login, key, path_geojson, start_date, end_date, name, product_type, cloud, filepath):    """    :param login: 欧空局账号,字符串类型    :param key: 欧空局密码,字符串类型    :param path_geojson: 兴趣区路径及文件名    :param start_date: 开始时间,字符串    :param end_date: 结束时间,字符串    :param name: 卫星名称    :param product_type: 卫星类型    :param cloud: 云量筛选,格式:(0,15)    :param filepath: Url保存路径及文件名    :return: 返回存有下载链接的excel路径    """    api = SentinelAPI(login, key, 'https://scihub.copernicus.eu/dhus')    # 登陆账号https://scihub.copernicus.eu/apihub/    footprint = geojson_to_wkt(read_geojson(path_geojson))    # 读取兴趣区,兴趣区由http://geojson.io导出    products = api.query(footprint,                         date=(start_date, end_date),  # 搜索的日期范围                         platformname=name,   # 卫星平台名,Sentinel-2                         producttype=product_type,  # 产品数据等级,Sentinel-2: S2MSI2A,S2MSI1C,S2MS2Ap/Sentinel-1:SLC,GRD,OCN                         cloudcoverpercentage=cloud)  # 云量百分比    # 搜索A、B双星的数据    row = 0    workbook_write = xlwt.Workbook(encoding='utf-8')    worksheet_write = workbook_write.add_sheet('Url_image')    for product in products:        # 通过for循环遍历并打印、下载出搜索到的产品文件名        info_product = api.get_product_odata(product)        # 通过OData API获取单一产品数据的主要元数据信息        worksheet_write.write(row, 0, info_product['url'])        worksheet_write.write(row, 1, info_product['title'])        print(info_product['title'])        # print(product_info['url'])        # 打印下载的产品数据文件名,id/uuid代码编号,size数据大小,title,url链接,md5,date时间        # api.download(product)        row += 1    workbook_write.save(filepath)    return filepath, api    # 循环结束后,保存表格def Download_image(filepath, Path_Download, Path_IDM, api):    workbook_read = xlrd2.open_workbook(filepath)    # 打开表格,创建工作空间    sheet1 = workbook_read.sheet_by_name('Url_image')    # 选择需要读取的sheet    link_list = sheet1.col_values(0)    # 获取第一列的数据    print('所有链接下载完成,现在开始下载对应数据')    num = 0    while link_list:        print('---------------------------------------------------')        num += 1        print('\n')        print('第' + str(num) + '次循环' + '\n')        id = link_list[0].split('\'')[1]        link = link_list[0]        info_product = api.get_product_odata(id)        print('查询当前列表里的第一个数据的状态')        if info_product['Online']:            print(info_product['title'] + '为:online产品')            print('加入IDM的下载列表中: ')            print('\n')            call([Path_IDM, '/d', link, '/p', Path_Download, '/n', '/a'])            link_list.remove(link)            call([Path_IDM, '/s'])        else:            print(info_product['title'] + '为:offline产品')            print('\n')            print('激活offline产品')            code_id = link_list[0].split('\'')[1]            api.trigger_offline_retrieval(code_id)            # 激活offline产品            print('检查任务列表里是否存在online产品: .........')            # 等待激活成功的时候,检查现在的列表里还有没有online产品            # 如果有online的产品那就下载            # 首先检查列表中是否需要下载的数据            if len(link_list) > 1:                # 记录列表里可以下载的链接,并在最后把它们删除                link_list_1 = []                # 开始寻找列表剩下的元素是否有online产品                for i in range(1, len(link_list)):                    id2 = link_list[i].split('\'')[1]                    link_1 = link_list[i]                    info_product2 = api.get_product_odata(id2)                    if info_product2['Online']:                        print(info_product2['title'] + '为Online产品')                        print('加入IDM的下载列表中: ')                        print('--------------------------------------------')                        call([Path_IDM, '/d', link_1, '/p', Path_Download, '/n', '/a'])                        # 在列表中加入需要删除产品的HTTP链接信息                        # 直接在link_list中删除会link_list的长度会发生改变,最终造成i的值超过link_list的长度                        link_list_1.append(link_1)                    else:                        continue                # 把已经下载的数据的链接给删除掉                if len(link_list_1) > 0:                    call([Path_IDM, '/s'])                    for link_2 in link_list_1:                        link_list.remove(link_2)            print('本轮次检查结束,开始等到40分钟')            # 将该激活的产品删除,再加入到最后            link_list.remove(link)            link_list.append(link)            # 两次激活offline数据的间隔要大于30分钟            for i in tqdm(range(int(1200)), ncols=100):                time.sleep(2)if __name__ == "__main__":    """说明文档:https://sentinelsat.readthedocs.io/en/latest/api_overview.html,    https://scihub.copernicus.eu/userguide/AdvancedSearch"""    login = '**********'    key = '********'    path_geojson = "G:/map.geojson"    start_date = "20230101"    end_date = "20230301"    name = 'Sentinel-2'    product_type = 'S2MSI2A'    cloud = (0, 15)    filepath = 'G:/url.xls'    # 存储下载链接的表格    filepath, api = Search_data(login, key, path_geojson, start_date, end_date, name, product_type, cloud, filepath)    Download_Path = 'G:/try_download/'    # 数据要下载的地址,IDM的下载地址    Path_IDM = "D:/IDM/IDMan.exe"    Download_image(filepath, Download_Path, Path_IDM, api)

        本博文代码是我很久之前写的了,结构有些冗余,但运行没有任何问题。同时有些借鉴的代码已经找不到原作者了,在这里先感谢大佬们的付出,如有侵权,请联系作者删除。

        如果大家在学习Python或者RS时有什么问题,可以随时留言交流!如果大家对批量处理有兴趣同样可以留言给博主,博主会分享相关代码以供学习!

来源地址:https://blog.csdn.net/m0_56729804/article/details/131209082

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯