首页 > 编程语言 >【Python&RS】基于Python批量下载哨兵二号数据

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

时间:2023-06-14 16:45:01浏览次数:50  
标签:info product RS Python list 二号 link print 下载

  学遥感的避免不了使用哨兵数据,毕竟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 date
import time
import xlwt
import xlrd2
# excel的读取和写入模块
from tqdm import tqdm


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
    # 循环结束后,保存表格


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时有什么问题,可以随时留言交流!如果大家对批量处理有兴趣同样可以留言给博主,博主会分享相关代码以供学习!

标签:info,product,RS,Python,list,二号,link,print,下载
From: https://www.cnblogs.com/RSran/p/17480703.html

相关文章

  • python基础25
    第三方模块的下载与安装内置的模块不能满足我们的需求,所以,大多数时候都需要借助于第三方模块第三方模块的下载需要基于网络下载如何下载和使用下载第三方模块需要pip工具方式一:命令行pipinstall模块名pipinstalldjango......
  • python匿名函数学习笔记
    当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便。list(map(lambdax:x*x,[1,2,3,4,5,6,7,8,9]))[1,4,9,16,25,36,49,64,81]由此,匿名函数lambdax:x*x实际上就是:deff(x):returnx*x关键字lambda表示匿名函数,冒号前......
  • python 操作文件 筛选 glob
    importglobimportosstr_addr=r"D:\360极速浏览器下载"str_join=os.path.join(str_addr,"*.*")glob.glob(str_join)list(glob.glob(str_join))==glob.glob(str_join)list(glob.iglob(str_join))==glob.glob(str_join)https://cloud.tencent.com/d......
  • 【技术积累】Python中的NumPy库【二】
    NumPy库的主要类有哪些?NumPy库的主要类包括:ndarray:N维数组对象,是NumPy最重要的类之一。它是Python中数组的基本数据结构,可以进行高效的数学计算和数据处理操作。ufunc:通用函数对象,是NumPy库中的另一个重要类。它是一种高效的元素级运算工具,提供了基本......
  • On Python
    Chapter11Test-DrivenDevelopmentTest-DrivenDevelopmentPrinciplesTDDconsistsofwritingtestcasesthatcoveradesiredfeature,thenwritingthefeatureitself.Inotherwords,theusuageexamplesarewrittenbeforethecodeevenexists.......
  • 对python生成器的理解
    什么是生成器?yield该函数没有运行而是返回了一个对象生成器是迭代器需要满足迭代器协议yield对函数做了什么和class定义的迭代器进行对比创建生成器要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:L......
  • 当SRS遇到K8s:如何构建海量推流源站?
    Photoby OscarIvanEsquivelArteaga on Unsplash文/杨成立本章描述了基于K8s,如何构建OriginCluster支持超多推流场景。OriginCluster通过配置其他源站的信息,在本源站没有流时查询到流的位置,通过RTMP302定向到指定源站,具体原理可以参考#464。主要应用场景如下:源站灾备:即使......
  • python 操作文件/文件夹 案例
    importosimportshutilimportglobstr_input=input("输入文件夹名即格式:")str_addr=r"D:\360极速浏览器下载"str_dest=os.path.join(str_addr,str_input)list_glob=list(glob.glob(os.path.join(str_addr,"*."+str_input+"*")))&......
  • 当SRS遇到K8s:如何实现高可用、回滚与灰度发布?
    Photoby LuisQuintero from Pexels文/杨成立服务的更新、回滚和灰度,是个简单的问题,如果加上一个条件"不中断服务的前提下",那么就是一个难题,如果再加上"大规模",那么就是K8S要解决的核心问题之一。坏消息是这个难搞的问题还真是流媒体服务的核心的、关键的、不可忽视的关键能......
  • 《最新出炉》系列初窥篇-Python+Playwright自动化测试-3-离线搭建playwright环境
    1.简介有些小伙伴或者童鞋们私信留言说自己是在公司局域网办公,或者公司为了安全对网络管控比较严格(尤其是一些大的国企、央企),总之就是一句话无法连到外网去在线下载,宏哥刚看到留言时觉得这问题还留言问啊,你找个有网的电脑下载好安装包然后安装就可以用了。(第一种情况及解决办法:带......