【Python&RS】GDAL批量裁剪遥感影像/栅格数据
GDAL(Geospatial Data Abstraction Library)是一个在X/MIT许可协议下的开源栅格空间数据转换库。它利用抽象数据模型来表达所支持的各种文件格式。它还有一系列命令行工具来进行数据转换和处理。
Python的GDAL库作为栅格数据的处理转换库,其支持几百种栅格数据格式,如常见的TIFF、ENVI、HFA、HDF4等。因为遥感影像大部分都是栅格数据,所以GDAL库非常适合处理遥感影像、如光谱指数计算、波段合成、批量下载等。
一、GDAL库的安装
因为博主的GDAL库的安装有些时候了,所以pip install 的方法能不能安装需要自己尝试。这里推荐大家下载对应包,使用本地安装。
1.打开GDAL库的下载链接,选择自己电脑Python对应的版本,别下载错了哦!
2.然后按住Win+R,输入cmd进入命令行。在cmd终端中,使用cd跳转至下载GDAL包的目录。如 cd /d G:\try\,G:\try\是你狭窄GDAL包的文件夹目录。然后在命令行里输入pip GDAL-3.4.3-cp38-cp38-win_amd64.whl,这是你下载的GDAL包的名称,每个人不一样,别傻乎乎地用我的!
3.可以在编译器里查看是否安装成功,博主使用的是PyCharm,在设置中可以看到是否安装成功。当然你也可以先编写程序,如果没安装成功,程序会报错=。=
二、编写程序
1.导入计算所需库
GDAL是我们安装的栅格数据处理库。os是系统操作库,用来遍历文件夹。time库用来计算程序执行时间,可以不要。
import time
import os
from osgeo import gdal
2.查看GDAL库中的裁剪函数
其中,out_raster是输出的栅格数据路径,in_raster是输入的栅格数据路径,cultineDSName是用于裁剪的矢量数据。
ds = gdal.Warp(out_raster, in_raster, format='GTiff',
cutlineDSName=shp_name,
cropToCutline=True,
cutlineWhere=None, dstNodata=0)
Warp函数主要参数说明,官网有说明文档。因为本人懒得翻译,所以这里参考了这篇文章:Python使用GDAL矢量裁剪栅格,设置背景值为空白(已解决)
gdal.Warp(options = [], format = 'GTiff', outputBounds = None,
outputBoundsSRS = one, xRes = None, yRes = None,
targetAlignedPixels = False, width = 0, height = 0, srcSRS = None,
dstSRS = None, srcAlpha = False, dstAlpha = False, warpOptions = None,
errorThreshold = None, warpMemoryLimit = None, creationOptions = None,
outputType = GDT_Unknown, workingType = GDT_Unknown, resampleAlg = None,
srcNodata = None, dstNodata = None, multithread = False, tps = False,
rpc = False, geoloc = False, polynomialOrder = None,
transformerOptions = None, cutlineDSName = None, cutlineLayer = None,
cutlineWhere = None, cutlineSQL = None, cutlineBlend = None,
ropToCutline = False, copyMetadata = True, metadataConflictValue = None,
setColorInterpretation = False, callback = None, callback_data = None):
其中:
options — 可以是一个字符串数组,一个字符串或者令其为空值,但是使用后面其他的参数来定义。
format — 输出的格式 (例如"GTiff"等)。
outputBounds — 在目标空间参考系统的输出数据集的范围,形式为 (minX,minY, maxX, maxY) 。
outputBoundsSRS — 如果在dstSRS中没有定义的话,使用这个关键字定义输出数据集的边界的空间参考系统。
xRes, yRes — 在目标参考系统中的像元大小。
targetAlignedPixels —是否强制输出边界为输出分辨率的倍数。
width — 输出栅格的像素列数。
height — 输出栅格的像素行数。
srcSRS —源空间参考系统。
dstSRS — 输出空间参考系统。
srcAlpha — 是否强制将输入数据集的最后一个波段作为alpha波段。
dstAlpha — 是否强制创建一个输出数据集的alpha波段。
outputType — 输出类型 (例如gdal.GDT_Byte等)
workingType — working type (gdal.GDT_Byte, etc…)
warpOptions —变形选项列表。
errorThreshold --近似转换的误差阈值(用像素表示) 。
warpMemoryLimit — 工作缓存大小,单位是bytes。
resampleAlg — 重采样模式。
creationOptions — 创建选项列表。
srcNodata — 源数据的nodata值。
dstNodata — 输出数据的nodata值。
multithread — 是否多线程计算和输入输出操作。
tps— 是否使用Thin Plate Spline GCP 转换器。
rpc— 是否使用RPC转换器。
geoloc — 是否使用GeoLocation数组转换器。
polynomialOrder — 多项式GCP插值的阶数。
transformerOptions — 转换参数
cutlineDSName — 剪切线数据集名称。这里的剪切线是指对影像进行剪切的时候所使用的矢量图层。
cutlineLayer — 剪切线图层名称。
cutlineWhere — 剪切线的WHERE语句。
cutlineSQL — 剪切线的SQL 语句。
cutlineBlend — 以像素为单位的剪切线混合距离。
cropToCutline — 是否使用剪切线的extent作为输出的界线。
copyMetadata — 是否拷贝源数据的元数据。
metadataConflictValue — 元数据冲突值。
setColorInterpretation — 是否强制将输入波段的颜色解释赋予输出波段。
callback — 回调函数。
callback_data — 回调函数数据
3.编写遍历代码,实现使用一个或多个shp批量裁剪多个栅格数据
shp_files = os.listdir(in_shape)
# 以列表展开所有目录下的文件名
for shp_file in shp_files:
# 从列表中遍历
if shp_file.endswith('.shp'):
# 判断是否为shp文件
shp_name = os.path.join(in_shape, shp_file)
# 定义shp文件的目录+名称
files = os.listdir(in_path)
# 打开需要裁剪的文件夹,将所有文件以列表的形式列出
for file in files:
if file[-4:] == '.tif':
# 判断文件是否为.tif结尾
filename = os.path.join(in_path, file)
# 确定找到的文件名
in_raster = gdal.Open(filename)
out_raster = os.path.join(out_path, file[-8:-4]+shp_file[:-4]+".tif")
ds = gdal.Warp(out_raster, in_raster, format='GTiff',
cutlineDSName=shp_name,
cropToCutline=True,
cutlineWhere=None, dstNodata=0)
ds = None
# 关闭处理空间,释放内存
三、完整代码
# -*- coding: utf-8 -*-
"""
@Time : 2023/5/19 9:05
@Auth : RS迷途小书童
@File :Clip Raster Data.py
@IDE :PyCharm
@Purpose :基于GDAL批量裁剪栅格数据
"""
import time
import os
from osgeo import gdal
def clip_batch(in_path, out_path, in_shape):
"""
:param in_path: 需要裁剪的文件夹
:param out_path: 输出文件夹
:param in_shape: 存放shp的文件夹
:return:
"""
shp_files = os.listdir(in_shape)
# 以列表展开所有目录下的文件名
for shp_file in shp_files:
# 从列表中遍历
if shp_file.endswith('.shp'):
# 判断是否为shp文件
shp_name = os.path.join(in_shape, shp_file)
# 定义shp文件的目录+名称
files = os.listdir(in_path)
# 打开需要裁剪的文件夹,将所有文件以列表的形式列出
for file in files:
if file[-4:] == '.tif':
# 判断文件是否为.tif结尾
filename = os.path.join(in_path, file)
# 确定找到的文件名
in_raster = gdal.Open(filename)
out_raster = os.path.join(out_path, file[-8:-4]+shp_file[:-4]+".tif")
ds = gdal.Warp(out_raster, in_raster, format='GTiff',
cutlineDSName=shp_name,
cropToCutline=True,
cutlineWhere=None, dstNodata=0)
ds = None
# 关闭处理空间,释放内存
if __name__ == "__main__":
# 直接执行函数
start = time.perf_counter() # 开始时间
in_shape = r"G:\pology" # 矢量范围
in_path = r"G:\30mlandcoverdata" # 输入栅格路径
out_path = r"G:\landusedata\3" # 输出栅格路径
clip_batch(in_path, out_path, in_shape)
end = time.perf_counter() # 结束时间
print('finish')
print('Running time: %s Seconds' % (end - start))
# 展示程序运行时间
如果大家在学习Python或者RS时有什么问题,可以随时留言交流!如果大家对批量处理有兴趣同样可以留言给博主,博主会分享相关代码以供学习!