查看原文
其他

还在担心卫星遥感影像数据下载的问题么?诚心奉献Sentinel哨兵数据高速下载方法(适用于其它卫星数据下载)

慧天地 2021-09-20

The following article is from Satellive Author 善睐-黄伟

点击图片上方蓝色字体“慧天地”即可订阅



(点击图片即可查看详细信息)

       卫星遥感影像下载是挡在地学及相关学科科研道路上的拦路虎,在国外可以通过对Google Earth Engine(GEE)中的Landsat,MODIS,哨兵二号卫星(Sentinel-2)等众多卫星影像数据直接进行云上处理获取感兴趣区域结果。它是如此之好,只可惜啊,像我这样的人,囊中羞涩怎会为其支付昂贵费用呢?特别是当领导要结果时,还是需要经过Google Driver box下载到本地的,而这也又是一笔不菲的费用。当然,这里就不点名那些同行们利用这个心理大势宣传GEE如何牛逼的复杂经济背景问题了。做研究嘛,还是要看在哪个国家的。至于道理,大家都懂,在国内下载影像数据,会有成千上万个草泥马从脑袋里面跑出来。不得不说,国家队的XX图发布的高分免费下载服务带来了巨大震撼,但那又如何,像我这样的科研贫民不还是搞不到被他们宣传成极品的数据么?怎么干掉这个拦路虎,怎么不再担心遥感数据下载、质量检查的事情呢?团队成员一直鼓励我探索,我想现在是时候诚心奉献哨兵影像数据高速下载方法了。


       欧空局的哨兵数据自然是精品,如果非要杠精地说美国航空航天局出品的Landsat系列卫星数据也很好,那也无可厚非。废话不多说,本文后续包含四个部分。在第一部分,在简要介绍哨兵影像数据的概况之后,以Sentinel-2数据为例,介绍如何通过ESA的API hub查询指定地理空间范围的Sentinel-2影像数据。在第二部分介绍如何通过通过配置aria2下载工具下载查询到的Sentinel-2影像数据,重点介绍python守护进程用于监控和管理aria2工具的重启。第三部分,介绍如何通过python程序更新Aria2的Sentinel-2数据下载清单。最后,一部分是题外话部分,不感兴趣可以不看。(篇幅较长,需多点耐心)


第一部分:哨兵数据介绍及使用API查询的两种方式(含代码)


       哨兵一号(Sentinel-1)是由两颗极轨卫星组成的,通过C波段合成孔径雷达成像仪,不受天气影响情况下获取图像。它是欧空局为哥白尼计划开发的五个任务中的第一个卫星计划。


       哨兵二号(Sentinel-2)也是由两颗极轨卫星组成的星座,两颗卫星在同一太阳同步轨道上,主要任务是监控陆地地表变化。幅宽是290km²,两颗卫星在无云条件下重访中纬度地区需要2~3天时间。官网上给出的覆盖区域描述:


The Sentinel-2 mission will provide systematic coverage over the following areas:

  • all continental land surfaces (including inland waters) between latitudes 56° south and 84° north(在北纬56° 和南纬84°之间的地表区域)

  • all coastal waters up to 20 km from the shore

  • all islands greater than 100 km²

  • all EU islands(整个欧洲大陆区域)

  • the Mediterranean Sea (地中海)

  • all closed seas (e.g. Caspian Sea).

       In addition, the Sentinel-2 observation scenario includes observations following member states or Copernicus Services requests (e.g. Antarctica, Baffin Bay).


图1 Sentinel-2(哨兵二号)卫星的重访周期

(图片来源:https://sentinel.esa.int/web/sentinel/user-guides/sentinel-2-msi/revisit-coverage)


      两颗卫星Sentinel-2A和Sentinel-2B在相同视角条件下,每5天重访陆地地表的大部分区域。由于相邻轨道的不同条带会重叠,重访部分区域的周期在不同视角条件下会不相同,但最多不超过10天。


图2 因邻近轨道重叠导致的重访周期差异

(图片来源:https://sentinel.esa.int/web/sentinel/user-guides/sentinel-2-msi/revisit-coverage)


       哨兵三号(Sentinel-3)是有欧空局和欧洲气象组织联合运营,提供可操作的海洋和陆地观测服务,主要目标是以高精度和可靠性测量海面地形、海陆表面温度和海陆表面颜色,以支持海洋预报系统、环境监测和气候监测。在哨兵三号卫星上通过海洋和陆地彩色仪器(OLCI)、海洋和陆地表面温度辐射计(SLSTR)、合成孔径雷达高度计(SRAL)、微波辐射计(MWR)和精密定轨(POD)仪器获得图像。


       哨兵五号(Sentinel-5)先驱者主要用于进行大气测量,用于空气质量、臭氧和紫外线辐射以及气候监测和预报,该卫星采用推扫式成像,对地球表面的扫描带宽度约为2600公里。除了UV1波段(7x28km²)和SWIR波段(7x7km²),所有光谱波段的典型像素大小(接近最低点)约为7x3.5km²。


       欧空局通过OpenHub和的API Hub向外提供数据服务,前面一个提供交互式地图查询数据,后一个通过API服务查询哨兵数据。这里重点介绍后面一个。第一种通过指定的Tile编号查询,直接上完整的python程序,首先用在欧空局官网上注册的账号密码作为参数传递到SentinelAPI函数中。


      敲重点:


import argparseimport datetimeimport globimport numpy as npimport osimport reimport timeimport sentinelsatimport zipfileimport timeimport pdbimport pandasfrom sentinelsat import SentinelAPI, read_geojson, geojson_to_wktfrom pandas import DataFrameimport pandas as pdimport hashlib
#用于获取下载哨兵二指定tile或者指定矢量的哨兵影像所需的URL地址、# md5校验码及长度#用于检验那些未下载完的链接,#以获取2019年全年武汉覆盖武汉区域的哨兵二号卫星2A级产品为例,# 黑色标注的startdate ,enddate ,level ,specify_tiles # 分别代表了所要查询的数据开始时间、结束时间、影像产品级别、指定的空间范围。(武汉刚好跨越5个tiles)
def getSentinelUrlByTiles():scihub_api = SentinelAPI('用户名', '密码', 'scihub.copernicus.eu/dh')startdate = sentinelsat.format_query_date('20190101')enddate = sentinelsat.format_query_date('20191231')# Search data, filtering by options.level = '2A'# tile = '50RLV'specify_tiles = ['49RGQ', '49RGP', '50RKU', '50RKV', '50RLV'] # 指定需要下载的tiles
final_urls = DataFrame()url_list = []md5_list = []for tile in specify_tiles:products = scihub_api.query(beginposition=(startdate, enddate),platformname='Sentinel-2',producttype='S2MSI%s' % level,cloudcoverpercentage=(0, 100), filename='*T%s*' % tile)

products_df = scihub_api.to_dataframe(products)#使用print(products_df)会看到下面的结果,其中id,md5,url最为重要
# {'id': 'd9c11a08-9548-423a-9d5b-3790bdd1949b', # 'title': 'S2B_MSIL1C_20180322T031539_N0206_R118_T49SCS_20180322T080731', # 'size': 557305492, # 'md5': 'A4DEE331BABF5D81FEEFED7E8F152E1A', # 'date': datetime.datetime(2018, 3, 22, 3, 15, 39, 27000), # 'footprint': 'POLYGON((109.12450894645511 32.434247217341294,109.15551946020656 32.55886040012398,109.19500574164893 32.7064511260414,109.23422411890954 32.85418162235375,109.27416742227145 33.00170389409306,109.31402177718599 33.149262433169554,109.35311404383268 33.297123960618194,109.38830946718173 33.42770696377061,110.02964494156487 33.435778798872015,110.04040193865697 32.44547285973725,109.12450894645511 32.434247217341294))', 'url': "scihub.copernicus.eu/dh('d9c11a08-9548-423a-9d5b-3790bdd1949b')/$value", 'Online': False, 'Creation Date': datetime.datetime(2018, 3, 22, 11, 36, 6, 645000), 'Ingestion Date': datetime.datetime(2018, 3, 22, 11, 25, 45, 119000)}
for i in range(len(products_df)):product = scihub_api.get_product_odata(products_df.iloc[i]['uuid'])print(product['url'])url_list.append(product['url'])print(product['md5'])md5_list.append((product['md5']))
final_urls['url'] = url_listfinal_urls['md5'] = md5_list
final_urls.to_csv("finale_urls_md5.csv", index=False)# 这里的md5一定要记录下来
# 第二种方式是,通过geojson指定的空间范围对影像数据进行查询,# 如何获得geojson这个事情就不在这里介绍了。# 同样得到一个pandas products_df 和之前是样的。# 最后的记过可以输出到csv文件中。# footprint = geojson_to_wkt(read_geojson('test.geojson'))# products = scihub_api.query(footprint,# beginposition=(startdate, enddate),# platformname='Sentinel-2')
# convert to Pandas DataFrame# products_df = scihub_api.to_dataframe(products)# print("............")# print(products_df)# pass


第二部分:Aria2下载工具配置(以windows下面的配置文件为例)

最重要的就是aria2.conf这个配置文件,标注黑色的地方,dir,input-file,http-user,http-passwd 分别表示目录、要下载数据的链接地址(存储在文本文件中),第三个是用户名,第四个是访问密码。其它配置包括自动续传、不覆盖之前已下载的文件等。如果不是因为知乎需要XX度账号上传附件,我还真是会全部上传aria2的配程序包。(XX度总是那么坑爹,这里不多说了)

## '#'开头为注释内容, 选项都有相应的注释说明, 根据需要修改 #### 被注释的选项填写的是默认值, 建议在需要修改时再取消注释 #### 文件保存相关 ### 文件的保存路径(可使用绝对路径或相对路径), 默认: 当前启动位置dir=GPPinput-file=5368574491-download_GPP.txt# 启用磁盘缓存, 0为禁用缓存, 需1.16以上版本, 默认:16Mdisk-cache=32M# 文件预分配方式, 能有效降低磁盘碎片, 默认:prealloc# 预分配所需时间: none < falloc < trunc < prealloc# NTFS建议使用fallocfile-allocation=none# 断点续传continue=trueallow-overwrite=false## 下载连接相关 ### 最大同时下载任务数, 运行时可修改, 默认:5max-concurrent-downloads=10# 同一服务器连接数, 添加时可指定, 默认:1max-connection-per-server=5# 最小文件分片大小, 添加时可指定, 取值范围1M -1024M, 默认:20M# 假定size=10M, 文件为20MiB 则使用两个来源下载; 文件为15MiB 则使用一个来源下载min-split-size=10M# 单个任务最大线程数, 添加时可指定, 默认:5split=20# 整体下载速度限制, 运行时可修改, 默认:0#max-overall-download-limit=0# 单个任务下载速度限制, 默认:0#max-download-limit=0# 整体上传速度限制, 运行时可修改, 默认:0max-overall-upload-limit=1M# 单个任务上传速度限制, 默认:0#max-upload-limit=1000000# 禁用IPv6, 默认:falsedisable-ipv6=falsemax-download-result=1000000max-tries=50http-user=XXXXXhttp-passwd=YYYY# 从会话文件中读取下载任务always-resume=truemax-file-not-found=100# 在Aria2退出时保存`错误/未完成`的下载任务到会话文件save-session=aria2.session# 定时保存会话, 0为退出时才保存, 需1.16.1以上版本, 默认:0#save-session-interval=60## RPC相关设置 ### 启用RPC, 默认:falseenable-rpc=true# 允许所有来源, 默认:falserpc-allow-origin-all=true# 允许非外部访问, 默认:falserpc-listen-all=true# 事件轮询方式, 取值:[epoll, kqueue, port, poll, select], # 不同系统默认值不同#event-poll=select# RPC监听端口, 端口被占用时可以修改, 默认:6800#rpc-listen-port=6800# 设置的RPC授权令牌, v1.18.4新增功能, # 取代 --rpc-user 和 --rpc-passwd 选项#rpc-secret=mivm.cn# 设置的RPC访问用户名, 此选项新版已废弃, 建议改用 --rpc-secret 选项#rpc-user=<USER># 设置的RPC访问密码, 此选项新版已废弃, 建议改用 --rpc-secret 选项#rpc-passwd=<PASSWD>## BT/PT下载相关 ### 当下载的是一个种子(以.torrent结尾)时, 自动开始BT任务, 默认:truefollow-torrent=true# BT监听端口, 当端口被屏蔽时使用, 默认:6881-6999listen-port=51413# 单个种子最大连接数, 默认:55#bt-max-peers=55# 打开DHT功能, PT需要禁用, 默认:trueenable-dht=true# 打开IPv6 DHT功能, PT需要禁用#enable-dht6=false# DHT网络监听端口, 默认:6881-6999#dht-listen-port=6881-6999# 本地节点查找, PT需要禁用, 默认:false#bt-enable-lpd=true# 种子交换, PT需要禁用, 默认:trueenable-peer-exchange=true# 每个种子限速, 对少种的PT很有用, 默认:50K#bt-request-peer-speed-limit=50K# 客户端伪装, PT需要peer-id-prefix=-TR2770-user-agent=Transmission/2.77# 当种子的分享率达到这个数时, 自动停止做种, 0为一直做种, 默认:1.0seed-ratio=0.1# 强制保存会话, 即使任务已经完成, 默认:false# 较新的版本开启后会在任务完成后依然保留.aria2文件#force-save=false# BT校验相关, 默认:true#bt-hash-check-seed=true# 继续之前的BT任务时, 无需再次校验, 默认:falsebt-seed-unverified=true# 保存磁力链接元数据为种子文件(.torrent文件), 默认:false#bt-save-metadata=true


 以本地电脑的D盘目录为例,说明下载步骤,首先要点击和运行EasyWebSvr.exe这个可执行程序,做一个web服务层。按照之前的配置文件配置好aria2.conf,如图3所示:


图3. aria2文件夹中的有关文件


       打开EasyWebSrc.exe的配置界面,如图4所示,设置主目录为当前aria2配置文件所在目录,确定其已打开。


图4.EasyWebSrc.exe的配置界面


      之前提到过,通过api hub访问哨兵数据集会有一些约束:The API Hub is managed with the same quota restrictions, ie. a limit of two parallel downloads per user. The site is publishing precisely the same data content as the Scientific Data Hub (both Sentinel-1 and Sentinel-2). (也就是一个用户最大的并行下载速度是有限制的,而且还有约束条件,例如经常用一个机器一个账户下载,机器的IP会被锁定,账号会受到限制)


       aria2虽然下载速度挺快,但是在尝试多次下载失败后,不会重新下载对应的链接了。因此,我在这里使用一个downloadermanagy.py的文件,这个文件在图3所示的目录中有显示。具体给出python代码,这个代码通过子进程模块,调用aria2c.exe这个可执行文件,从子进程的标准输出中查看下载数据的打印信息,如果发现最后一条打印信息一直不发生变化,则调用terminate()函数终止该子进程,然后重新执行循环。(需要注意的是python没有goto语句,可以安装一个with-go模块实现循环跳转)


#!/usr/bin/env python#coding : utf-8import subprocessimport hashlibimport os,timeimport sysfrom subprocess import Popen, PIPEimport timefrom goto import with_gotodef getMd5OfFile(fname):if not os.path.exists(fname):return Nonetry:f = file(fname, 'rb')md5 = hashlib.md5()while True:# 每次读16Kd = f.read(16384)if not d:breakmd5.update(d)f.close()return md5.hexdigest()except Exception :return None@with_gotodef start_download():label .begininput_file = "user2.txt"image_count = len(open(input_file, 'rU').readlines())last_line = ""sleep_total_second = 60#print(image_count)with Popen("D:\\aria2\\aria2c.exe --conf-path=aria2.conf", shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=20000, universal_newlines=True) as p:for line in p.stdout:#如果最后一行一直没有发生变化,则向原来的进程发中止信号,并退出#print(line)#print(len(line))if (line == '\n' and last_line==""):continueelse:if last_line == "":last_line = linecontinueelse:#line = line.strip()if last_line == line:sleep_total_second = sleep_total_second - 1time.sleep(1)if sleep_total_second == 0:p.terminate()breakelse:if line == '\n':continueelse:print(line)last_line = linecontinuegoto .beginif __name__ == "__main__":#cmd = 'cmd.exe D:\\aria2\\Start.bat'#首先看需要下载多少个文件start_download()


   也可以通过点击EasyWebSrc.exe的右键,找到浏览主页,看到如图5所示的数据下载界面。


图5 aria2数据下载界面


       经过这样的折腾,aira2下载工具就能快速下载那些失败的链接了。ESA会定期维护数据集下载服务器,因此,链接暂时失效是难以避免的。我们认为,这个小程序会比较好的解决这个问题。


第三部分:更新aria2下载工具的下载清单。


       aria2的失效链接自动重启配置好后,另一个比较重要的问题是,它内部循环迭代查询是否还有未下载的影像。这就使得一个包含一万个链接的文件,总会从开头一直扫描到结尾,比较浪费时间。因此,继续用python程序进行判断,将已经完成的哨兵数据链接从未完成的哨兵数据链接中剔除,代码如下:


import argparseimport datetimeimport globimport numpy as npimport osimport reimport timeimport sentinelsatimport zipfileimport timeimport pdbimport pandasfrom sentinelsat import SentinelAPI, read_geojson, geojson_to_wktfrom pandas import DataFrameimport pandas as pdimport hashlib#printPath功能是打印所有当前目录下的文件名def printPath(level, path):allFileNum = 0
dirList = []fileList = []files = os.listdir(path)dirList.append(str(level))for f in files:if (os.path.isdir(path + '/' + f)):if (f[0] == '.'):passelse:dirList.append(f)if (os.path.isfile(path + '/' + f)):fileList.append(f)i_dl = 0for dl in dirList:if (i_dl == 0):i_dl = i_dl + 1else:printPath((int(dirList[0]) + 1), path + '/' + dl)final_list=[]for fl in fileList:allFileNum = allFileNum + 1final_list.append(os.path.join(path, fl))return final_list#checkwhichURL_not_done接受两个参数,第一个参数是通过上一个函数获得#的影像文件名#第二个参数是包含ur和mdf信息的csv文件,#之前第一个python代码就是获得了这两个有效信息,#使用md5_hash = hashlib.md5()进行计算文件的md5值,#然后设置要对比的链接下载文件csv中是否有该md5信息,#如果有则将dataframe的flag例置为1,#最后打印出来的url文件就是未下载完的哨兵影像链接,#继续按照第二和第三部分的说明进行下载即可。#def checkwhichURL_not_done(tmp_filelist, urls_list_df):not_download_url=[] #最后未被下载的urldf = urls_list_df.copy()for file in tmp_filelist:md5_hash = hashlib.md5()with open(file, "rb") as f:# Read and update hash in chunks of 4Kfor byte_block in iter(lambda: f.read(40960), b""):md5_hash.update(byte_block)md5=str.upper(md5_hash.hexdigest())#print(".................")#print(md5)mask = (df['md5'] == md5)df.loc[mask, 'flag'] = 1df = df.copy()
df=df.fillna(0).copy()#最后找到所有那些flag=0.0的mask = (df['flag'] =="0.0")df_extra = df.loc[mask]df_extra = df.copy()print(df_extra['url'])passif __name__ == "__main__":strPath=r"D:\test_MODIS"tmp_filelist=printPath(1,r"D:\test_MODIS")#print(tmp_filelist)urls_list_df = pd.read_csv("finale_urls_md5.csv")checkwhichURL_not_done(tmp_filelist,urls_list_df )pass

第四部分:不算题外话的题外话

       在详细介绍了如何快速下载哨兵卫星数据之后,我们聊点别的。实际上对遥感数据的获取和查询一直是个火热的话题。例如,当我们想研究全球湖泊水库的面积变化时,我想这种难度是极其高的,主要原因是,数据的下载会浪费我们足够多的时间。另外一方面,小范围小区域的遥感影像数据查询下载其实更加重要。例如,我们只需要武汉东湖的卫星遥感影像数据,结果不得不下载整个整个武汉区域甚至更大范围的数据。也许对于GIS和遥感专业的人来说,遥感数据本身就是大范围的,但站在普通用户的角度,有可能我们需要的仅仅是某块小试验田的单像素长序列数据。这样的话,本身的那种大范围的思想就不一样了。可以很明确的告诉大家,时至完稿日我大天朝尚无一个卫星遥感机构考虑到这个问题。为了解决这个问题,我们团队研发一套卫星遥感数据服务平台,致力于解决遥感数据下载难使用难的问题。我们的目标是:让小范围遥感影像数据下载如泉涌,让小区域遥感影像数据交易成主流。诚挚希望大家继续关注我们善睐(Satellive)团队。最后,愿大家收获数据下载技能的同时帮忙转载此文。与此同时,我们呼吁大家都能把下载的数据分享在善睐(Satellive)卫星遥感数据服务平台上,本平台预计2020年5月4日青年节上线,敬请关注。我们的愿望是让其他科研用户不再痛苦地等待数据下载。在转载前,记得联系我们关注本公众号(Satellive)并在后台留言或邮件至huangwei0316@hust.edu.cn。我们保留对所转载图文内容和代码的所有权利。谢谢大家!


(点击图片即可查看详细信息)




内容转载、商务活动、投稿等合作请联系

微信号:huitiandi321

邮箱:geomaticshtd@163.com

欢迎关注慧天地同名新浪微博:

ID:慧天地_geomaticser

往期精彩推荐

将卫星遥感图像分析拓展至商业领域,以色列卫星数据AI分析公司Oneview获数百万美元融资
【蝗虫监测】“珠海一号”遥感卫星监测巴基斯坦蝗灾区域

遥感卫星带你看:齐鲁大地复工复产忙




《慧天地》敬告

《慧天地》公众号聚焦国内外时空信息科技前沿、行业发展动态、跨界融合趋势,探索企业核心竞争力,传播测绘地理信息文化,为测绘、地信、遥感等相关专业的同学提供日常学习、考研就业一站式服务,旨在打造政产学研用精准对接的平台。《慧天地》高度重视版权,对于原创、委托发布的稿件,会烦请作者、委托方亲自审核通过后才正式推发;对于来自网站、期刊、书籍、微博、微信公众号等媒介的稿件,会在作者栏或者文章开头显著标明出处,以表达对作者和推文引用平台版权的充分尊重和感谢;对于来源于网络作者不明的优质作品,转载时如出现侵权,请后台留言,我们会及时删除。感谢大家一直以来对《慧天地》的关注和支持!


——《慧天地》运营团队

编辑:张自轩 审核:富裕 张自轩
指导:万剑华教授
: . Video Mini Program Like ,轻点两下取消赞 Wow ,轻点两下取消在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存