本文介绍基于Python 语言,结合已知研究区域 中所覆盖的全部遥感影像 的分幅条带号 ,从大量的遥感影像文件 中筛选落在这一研究区域中 的遥感影像文件的方法。
首先,先来明确一下本文所需实现的需求。现已知一个研究区域 (四川省),且已知覆盖这一研究区域 所需的全部遥感影像的分幅条带号 (这里就以Sentinel-2数据所采用的分幅规则为例来介绍),如下图所示。
其中,矢量图层上的标签 (Label )就是所需的遥感影像的分幅条带号 ;且这一矢量要素的属性表中,有具体每一个分幅条带号的具体字段(如上图红色方框所示的那一列)。
同时,我们还下载好了大量的遥感影像------这些遥感影像数量众多,既有位于这一研究区域内 的遥感影像,同时还有位于研究区域外 的。其中,这里所有的遥感影像都保存在一个大文件夹 下,而这一大文件夹 下还有多个子文件夹 ,具体遥感影像就存在于子文件夹中;如下图所示。
其中,红色框内的文件夹即为前述"大文件夹 ",紫色框内的每一个文件夹即为前述"子文件夹 "。此外,每一个子文件夹的命名也是和遥感影像的分幅条带号 对应的,比如43LCC
这一个子文件夹就是保存了UTM 编号为43
的网格内的全部遥感影像。这里关于Sentinel-2 遥感影像分幅条带号的介绍,如果大家有需要,可以参考哨兵2号Sentinel-2分幅条带介绍与MGRS网格矢量文件获取这篇文章。
同时,在每一个遥感影像文件 的文件名 中,都有分幅条带号 这一字段;例如,打开43LCC
这一子文件夹,如下图所示。
我们希望实现的,就是基于上图所示的研究区域内遥感影像的分幅条带号信息,在大量的遥感影像中筛选出这些分幅对应的遥感影像文件,并将其通过复制的方式放入到一个新的结果文件夹中。
了解了具体需求,我们就可以开始代码的撰写。首先,本文所需的完整代码如下所示。
python
# -*- coding: utf-8 -*-
"""
Created on Fri Feb 3 18:33:11 2023
@author: fkxxgis
"""
import os
import xlrd
import shutil
xls_file = r"E:\02_Project\Sentinel.xls"
tif_path = r"G:\S2_CSI_LCC_product\LCC_10days_2020"
result_path = r"G:\Select"
book = xlrd.open_workbook(xls_file)
sh = book.sheet_by_index(0)
row_num = sh.nrows
for row in range(1, row_num):
mgrs = sh.cell(row,6).value
utm = mgrs[0:2]
for root, dirs, files in os.walk(tif_path):
for name in dirs:
if name[0:2] == utm:
for root_1, dirs_1, files_1 in os.walk(os.path.join(root, name)):
for name_1 in files_1:
if name_1.find(mgrs) != -1:
if not os.path.exists(os.path.join(result_path, mgrs)):
os.makedirs(os.path.join(result_path, mgrs))
print("Make " + mgrs + " path.")
shutil.copy(os.path.join(root, name, name_1), os.path.join(result_path, mgrs, name_1))
其中,我们需要导入os
、xlrd
与shutil
等3
个Python 库,分别实现系统文件遍历、Excel 数据读取与研究区域内遥感影像数据的复制。其中,关于xlrd
库的配置,如果大家是用的Anaconda 环境,可以参考Python表格处理模块xlrd在Anaconda中的安装这篇文章。此外,我们首先需要将本文开头提及的表示遥感影像数据分幅条带号 的矢量文件的属性表导出(通过"System Toolboxes "→"Conversion Tools.tbx "→"Excel "→"Table To Excel "选项,如下图所示),保存为.xls
格式的表格文件,从而方便我们后期代码对数据的读取。
在代码中,xls_file
表示我们将属性表导出后得到的.xls
格式的表格文件,tif_path
表示存放所有遥感影像的大文件夹,result_path
则表示找到我们所需的结果遥感影像文件后,希望将其复制到的路径。
随后,我们通过xlrd.open_workbook()
函数打开.xls
格式的表格文件,读取其中的数据并获取其行数row_num
;接下来,我们即可对这一表格文件的单元格数据加以遍历,也就是代码中的第1
个for
循环------我们从第2
行开始(因为第1
行是表头),读取每一行第7
列的数据(也就是存放有遥感影像分幅条带号的那一列),从而依次获取所需的遥感影像条带号。
接下来,由于遥感影像的分幅条带号 的前两位,以及前述子文件夹名称的前两位,都是表示UTM 编号的两位数字,因此我们通过utm = mgrs[0:2]
这句代码,截取当前遥感影像分幅条带号 的前两位,并通过os.walk()
函数进行遍历,通过一个if
判断语句找到大文件夹下对应的子文件夹;随后,在这一子文件夹中同样通过os.walk()
函数,进行遥感影像文件的遍历------也就是代码中第2
个、第3
个、第4
个for
循环所做的事情。
接下来,针对遍历得到的子文件夹中每一个遥感影像文件,我们通过.find()
函数找到所有满足这一分幅条带号 的遥感影像文件,也就是代码中第5
个for
循环与第2
个if
判断语句的工作。找到符合当前分幅条带号的遥感影像文件后,我们即可开始将其复制到目标文件夹中。
这里还有一个需求,因为我们这里保存的是多时相遥感影像数据(即每一个分幅条带号 对应着多个不同时相 的遥感影像文件),因此我们希望在目标文件夹中,同样用各个分幅条带号 作为名称,创建多个子文件夹;然后将当前分幅条带号 对应的全部遥感影像数据放入这一文件夹中。基于此,我们通过os.path.exists()
函数判断是否存在指定的子文件夹,如果不存在的话就新建这一文件夹;随后,通过shutil.copy()
函数复制这些遥感影像文件。
运行上述代码,最终我们得到的结果如下图所示;其中,每一个子文件夹都表示一个分幅条带号 ,子文件夹内即为这一分幅条带号 所对应的全部时相的遥感影像文件。
至此,大功告成。