gdal矢量裁剪栅格(遥感影像)

裁剪(矢量裁剪栅格)

GDAL OGR


#矢量批量裁剪栅格影像
#@liuxy


from osgeo import gdal
import os

input_file = r'C:\Users\BNU\Desktop\temp\HNDK\GY_2020\TIFF' #栅格数据(可以是多个栅格)
output_file = r'C:\Users\BNU\Desktop\temp\HNDK\GY_2020\clip/' #裁剪后存放的文件夹
input_shape = r'C:\Users\BNU\Desktop\temp\HNDK\GY_2020\TIFF\TEST1.shp'  #矢量数据
prefix = '.tif'

file_all = os.listdir(input_file) 
# print(file_all)
for file_i in file_all:
    if file_i.endswith(prefix):
        file_name = input_file + "\\"+file_i

        data = gdal.Open(file_name)
        ds = gdal.Warp(output_file + os.path.splitext(file_i)[0] + '_Clip1.tif',
              data,
              format = 'GTiff',
              cutlineDSName = input_shape,      
            #   cutlineWhere= "TBLXMC = '农作物'",#特定字段筛选
              cropToCutline=True, # 保证裁剪后影像大小跟矢量文件的图框大小一致
              outputType=gdal.GDT_Int16,
            #   creationOptions=["TILED=YES", "COMPRESS=LZW"],
              dstNodata = 0)

效果

裁剪前(栅格+矢量)
裁剪前
裁剪后
在这里插入图片描述

遇到问题,解决问题

当进行耕地矢量进行裁剪时,如果矢量面存在拓扑错误,相交等出现如下报错

Warning1: RingSelf-intersectionatornearpoint112 .4866642030000334 .830899357000078 

ERROR1: Cutlinepolygonisinvalid.

参考 https://blog.csdn.net/qq_45723511 。这里给出一种使用python+ogr函数库的解决方法。


#矢量批量裁剪栅格影像
#@liuxy

from osgeo import gdal,ogr
import os

# # # 注册所有的驱动
ogr.RegisterAll()
gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES")
gdal.SetConfigOption("SHAPE_ENCODING", "GBK")

#------------------------修改拓扑错误(相交)---------------------#
def s_shp_si(shpFile):
    out_shp = shpFile[:-4] + '_ssi' + '.shp'
    # print(out_shp)
    # 打开数据
    ds = ogr.Open(shpFile, 0)
    if ds is None:
        print("打开文件 %s 失败!" % shpFile)
        return
    print("打开文件%s成功" % shpFile)
    # 获取该数据源中的图层个数,一般shp数据图层只有一个,如果是mdb、dxf等图层就会有多个
    m_layer_count = ds.GetLayerCount()
    m_layer = ds.GetLayerByIndex(0)
    if m_layer is None:
        print("获取第%d个图层失败\n", 0)
        return
    # 创建输出文件
    driver = ogr.GetDriverByName('ESRI Shapefile')
    if os.path.exists(out_shp):
        driver.DeleteDataSource(out_shp)
    outds = driver.CreateDataSource(out_shp)
    outlayer = outds.CreateLayer(out_shp[:-4], geom_type=ogr.wkbPolygon, options=["ENCODING=GBK"])
    # 获取输出层的要素定义
    outLayerDefn = outlayer.GetLayerDefn()
    # 对图层进行初始化,如果对图层进行了过滤操作,执行这句后,之前的过滤全部清空
    m_layer.ResetReading()
    # 获取投影
    prosrs = m_layer.GetSpatialRef()
    # 添加字段
    inLayerDefn = m_layer.GetLayerDefn()
    for i in range(0, inLayerDefn.GetFieldCount()):
        fieldDefn = inLayerDefn.GetFieldDefn(i)
        outlayer.CreateField(fieldDefn)

    # loop through the input features
    m_feature = m_layer.GetNextFeature()
    while m_feature:
        # print(m_feature)
        o_geometry = m_feature.GetGeometryRef()
        # 关键,合并几何
        o_geometry = o_geometry.Union(o_geometry)
        outfeature = ogr.Feature(outLayerDefn)
        outfeature.SetGeometry(o_geometry)
        # 遍历每个要素的字段,并设置字段属性
        for i in range(0, outLayerDefn.GetFieldCount()):
            print(outLayerDefn.GetFieldDefn(i).GetNameRef())
            outfeature.SetField(outLayerDefn.GetFieldDefn(i).GetNameRef(), m_feature.GetField(i))
        outlayer.CreateFeature(outfeature)
        # dereference the features and get the next input feature
        outfeature = None
        m_feature = m_layer.GetNextFeature()

    ds.Destroy()
    outds.Destroy()
    # 保存投影文件

    prjfile = (out_shp[:-4] + '.prj')
    fn = open(prjfile, 'w')
    fn.write(prosrs.ExportToWkt())
    fn.close()

    return out_shp


#-----------------路径文件-------------
input_file = r'C:\Users\BNU\Desktop\temp\HNDK\GY_2020\TIFF' #栅格数据(可以是多个栅格)
output_file = r'C:\Users\BNU\Desktop\temp\HNDK\GY_2020\clip/' #裁剪后存放的文件夹
# input_shape = r'C:\Users\BNU\Desktop\temp\HNDK\GY_2020\TIFF\TEST1.shp'  #矢量数据(不存在拓扑错误)
input_shape = r'D:\矢量数据\shp\GY_SHP_CROP.shp'
prefix = '.tif'

## 矢量拓扑错误(相交)的改正
## 如果不存在拓扑错误(相交),可以将下面两行注销掉
input_shape = s_shp_si(input_shape) #经过了处理矢量会存在同级文件夹中
print(input_shape,'input_shape_correct')


file_all = os.listdir(input_file) 
# print(file_all)
for file_i in file_all:
    if file_i.endswith(prefix):
        file_name = input_file + "\\"+file_i

        data = gdal.Open(file_name)
        ds = gdal.Warp(output_file + os.path.splitext(file_i)[0] + '_Clip1.tif',
              data,
              format = 'GTiff',
              cutlineDSName = input_shape,      
            #   cutlineWhere= "TBLXMC = '农作物'",#特定字段筛选
              cropToCutline=True, # 保证裁剪后影像大小跟矢量文件的图框大小一致
              outputType=gdal.GDT_Int16,
            #   creationOptions=["TILED=YES", "COMPRESS=LZW"],
              dstNodata = 0)

参考链接

https://blog.csdn.net/qq_44935981/article/details/122141636
https://blog.csdn.net/weixin_42990464/article/details/117693553

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值