首页 > 编程语言 >【Python&GIS】基于Python实现栅格转面、面转栅格(栅格、矢量互转)

【Python&GIS】基于Python实现栅格转面、面转栅格(栅格、矢量互转)

时间:2023-11-08 11:35:55浏览次数:35  
标签:shp raster Python 矢量 栅格 互转 output ds

        各位好,我又来水文章了。最近因为同事在做生态服务相关的项目,需要对矢量数据进行操作,然后我就查了查相关资料,今天就和大家分享一下如何使用Python的GDAL库实现栅格转要素、要素转栅格(栅格、矢量互相转换)。其实我之前已经分享过栅格转面和计算要素面积的代码,大家感兴趣可以去看下:【Python&GIS】GDAL栅格转面&计算矢量面积

一、栅格转面

        这里栅格对应的值被写入矢量的属性字段Value中。注释很详细不多说。

def Raster_To_Vector(input_raster, output_shp):
    """
    :param input_raster: 输入需要转换的栅格数据
    :param output_shp: 输出矢量的路径
    :return:None
    """
    print("正在栅格转面。。。")
    # 栅格转面
    ds_raster = gdal.Open(input_raster)  # 读取路径中的栅格数据
    band_raster = ds_raster.GetRasterBand(1)  # 获取需要转为矢量的波段
    proj_raster = osr.SpatialReference()
    proj_raster.ImportFromWkt(ds_raster.GetProjection())
    # 将栅格数据的投影信息赋值给矢量
    driver = ogr.GetDriverByName("ESRI Shapefile")
    if os.path.exists(output_shp):  # 若文件已经存在,则删除它继续重新做一遍
        driver.DeleteDataSource(output_shp)
    polygon = driver.CreateDataSource(output_shp)  # 创建数据资源
    layer_polygon = polygon.CreateLayer("Shp", srs=proj_raster, geom_type=ogr.wkbMultiPolygon)  # 创建图层,定义多面
    new_field = ogr.FieldDefn('value', ogr.OFTReal)  # 给目标shp文件添加一个字段,用来存储原始栅格的pixel value
    layer_polygon.CreateField(new_field)
    gdal.FPolygonize(band_raster, None, layer_polygon, 0)  # 核心函数,执行的就是栅格转矢量操作
    polygon.SyncToDisk()
    polygon = None

二、面转栅格

        这里有个大问题!!!GDAL里面的转换函数里的参数是需要参考值的,所以我们需要输入一个栅格作为参考,才能将矢量转为栅格。这就导致这个函数的应用非常局限,而GIS中的面转栅格就不要参考栅格,甚至还可以选择栅格大小。

        无语......,但这个函数也不是一无是处,这个函数可以将我们的深度学习样本转为栅格,懂我意思?我们在画样本时都是矢量,但有些模型的输入是需要栅格数据的,这个时候这个函数还是有点用的。

def Vector_To_Raster(input_shp, refer_raster, attribute, output_raster):
    """
    :param input_shp: 输入需要转换的矢量数据
    :param refer_raster: 输入参考栅格数据
    :param attribute: 输入栅格值对应的矢量字段
    :param output_raster: 输出栅格数据路径
    :return: None
    """
    ds_raster = gdal.Open(refer_raster)
    ds_proj = ds_raster.GetProjection()  # 投影信息
    ds_trans = ds_raster.GetGeoTransform()  # 仿射地理变换参数
    ds_width = ds_raster.RasterXSize  # 获取宽度/列数
    ds_height = ds_raster.RasterYSize  # 获取高度/行数
    ds_raster = None  # 释放内存
    del ds_raster
    driver = ogr.GetDriverByName("ESRI Shapefile")
    ds = driver.Open(input_shp, 1)
    layer = ds.GetLayer()  # 获取图层文件对象
    result = gdal.GetDriverByName('GTiff').Create(output_raster, ds_width, ds_height, bands=1, eType=gdal.GDT_Byte)
    result.SetGeoTransform(ds_trans)  # 写入仿射地理变换参数
    result.SetProjection(ds_proj)  # 写入投影信息
    band = result.GetRasterBand(1)
    band.SetNoDataValue(0)  # 忽略背景值
    band.FlushCache()  # 清空数据缓存
    # options = ["ATTRIBUTE=attribute", "CHUNKY SIZE=0", "ALL_TOUCHED=False"]
    # 指定输入矢量数据的属性字段中的字段值作为栅格值写入栅格文件中,该值将输出到所有输出波段中。假如该值指定了,burn_Values参数的值将失效数可以设置为空。
    # 指定该运行操作的块的高度。该值越大所需的计算时间越小。如果该值没有设置或者设置为0则由GDAL的缓存大小根据公式:缓存所占的字节数/扫描函数的字节数得到。所以该值不会超出缓存的大小。
    # 设置为TRUE表示所有的像素接触到矢量中线或多边形,否则只是多边形中心或被Bresenham算法选中的部分。默认值为FALSE。简单来说,FALSE是八方向栅格化,TRUE是全路径栅格化。
    gdal.RasterizeLayer(result, [1], layer, burn_values=[1], options=[f"ATTRIBUTE={attribute}"])
    # 矢量转栅格函数。输出栅格,波段数,图层,栅格数值(可控失效),可选参数(栅格数值取字段)
    result = None
    del result, layer

三、完整代码

        没啥说的,注释很详细,用哪个函数就调用哪个函数即可!

# -*- coding: utf-8 -*-
"""
@Time : 2023/11/3 14:37
@Auth : RS迷途小书童
@File :Convert Raster And Vector.py
@IDE :PyCharm
@Purpose:栅格数据、矢量数据互相转换
"""
import os
from osgeo import gdal, osr, ogr


def Raster_To_Vector(input_raster, output_shp):
    """
    :param input_raster: 输入需要转换的栅格数据
    :param output_shp: 输出矢量的路径
    :return:None
    """
    print("正在栅格转面。。。")
    # 栅格转面
    ds_raster = gdal.Open(input_raster)  # 读取路径中的栅格数据
    band_raster = ds_raster.GetRasterBand(1)  # 获取需要转为矢量的波段
    proj_raster = osr.SpatialReference()
    proj_raster.ImportFromWkt(ds_raster.GetProjection())
    # 将栅格数据的投影信息赋值给矢量
    driver = ogr.GetDriverByName("ESRI Shapefile")
    if os.path.exists(output_shp):  # 若文件已经存在,则删除它继续重新做一遍
        driver.DeleteDataSource(output_shp)
    polygon = driver.CreateDataSource(output_shp)  # 创建数据资源
    layer_polygon = polygon.CreateLayer("Shp", srs=proj_raster, geom_type=ogr.wkbMultiPolygon)  # 创建图层,定义多面
    new_field = ogr.FieldDefn('value', ogr.OFTReal)  # 给目标shp文件添加一个字段,用来存储原始栅格的pixel value
    layer_polygon.CreateField(new_field)
    gdal.FPolygonize(band_raster, None, layer_polygon, 0)  # 核心函数,执行的就是栅格转矢量操作
    polygon.SyncToDisk()
    polygon = None


def Vector_To_Raster(input_shp, refer_raster, attribute, output_raster):
    """
    :param input_shp: 输入需要转换的矢量数据
    :param refer_raster: 输入参考栅格数据
    :param attribute: 输入栅格值对应的矢量字段
    :param output_raster: 输出栅格数据路径
    :return: None
    """
    ds_raster = gdal.Open(refer_raster)
    ds_proj = ds_raster.GetProjection()  # 投影信息
    ds_trans = ds_raster.GetGeoTransform()  # 仿射地理变换参数
    ds_width = ds_raster.RasterXSize  # 获取宽度/列数
    ds_height = ds_raster.RasterYSize  # 获取高度/行数
    ds_raster = None  # 释放内存
    del ds_raster
    driver = ogr.GetDriverByName("ESRI Shapefile")
    ds = driver.Open(input_shp, 1)
    layer = ds.GetLayer()  # 获取图层文件对象
    result = gdal.GetDriverByName('GTiff').Create(output_raster, ds_width, ds_height, bands=1, eType=gdal.GDT_Byte)
    result.SetGeoTransform(ds_trans)  # 写入仿射地理变换参数
    result.SetProjection(ds_proj)  # 写入投影信息
    band = result.GetRasterBand(1)
    band.SetNoDataValue(0)  # 忽略背景值
    band.FlushCache()  # 清空数据缓存
    # options = ["ATTRIBUTE=attribute", "CHUNKY SIZE=0", "ALL_TOUCHED=False"]
    # 指定输入矢量数据的属性字段中的字段值作为栅格值写入栅格文件中,该值将输出到所有输出波段中。假如该值指定了,burn_Values参数的值将失效数可以设置为空。
    # 指定该运行操作的块的高度。该值越大所需的计算时间越小。如果该值没有设置或者设置为0则由GDAL的缓存大小根据公式:缓存所占的字节数/扫描函数的字节数得到。所以该值不会超出缓存的大小。
    # 设置为TRUE表示所有的像素接触到矢量中线或多边形,否则只是多边形中心或被Bresenham算法选中的部分。默认值为FALSE。简单来说,FALSE是八方向栅格化,TRUE是全路径栅格化。
    gdal.RasterizeLayer(result, [1], layer, burn_values=[1], options=[f"ATTRIBUTE={attribute}"])
    # 矢量转栅格函数。输出栅格,波段数,图层,栅格数值(可控失效),可选参数(栅格数值取字段)
    result = None
    del result, layer


if __name__ == "__main__":
    shp = r"B:\Personal\彭俊喜\深度学习\CNN\0919小块实验/sample.shp"
    refer = r"B:\Personal\彭俊喜\深度学习\CNN\0919小块实验\example.tif"
    out = r"B:\Personal\彭俊喜\深度学习\CNN\0919小块实验\try.tif"
    Attribute = "AREA"
    Vector_To_Raster(shp, refer, Attribute, out)

        

        本文章主要是分享个人在学习Python过程中写过的一些代码。有些部分借鉴了前人以及官网的教程,如有侵权请联系作者删除,大家有问题可以随时留言交流,博主会及时回复。

标签:shp,raster,Python,矢量,栅格,互转,output,ds
From: https://www.cnblogs.com/RSran/p/17816985.html

相关文章

  • Python正则表达式入门
    正则表达式文本查找实例正则表达式主要是让使用者指定要查找的“模式”,而不是死板地查找固定的内容。不用正则表达式查找内容例如我们要查找长沙区号的电话号码,那么我们就需要知道特征,比如0731-84802110,0731是长沙的区号,紧接着就是-短横,然后是8位数字,那么我们就必须要符合这样......
  • Python - .egg 文件(python 蛋)
    Python什么是Python蛋(Pythonegg)在本文中,我们将介绍 Python 蛋(Python egg)是什么以及它在Python程序开发中的作用。Python蛋是一种用于管理和分发Python代码的软件包格式。它是一种打包、分发和安装Python代码的标准方式,允许开发者将其代码和相关依赖打包成一个可执......
  • mes登陆界面 python
    importtkinterastkfromtkinterimportmessageboxdefcheck_password():ifusername_entry.get()=="admin"andpassword_entry.get()=="password":messagebox.showinfo("登录成功","欢迎使用MES系统!")else:......
  • mes 数据库 python sqlite
    importsqlite3fromsqlite3importErrordefcreate_connection():conn=None;try:conn=sqlite3.connect(':memory:')#创建一个内存数据库。对于文件数据库,您可以使用文件路径。print(f'successfulconnectionwithsqliteversion{sqlite3.......
  • Python 既是解释型语言,也是编译型语言
    哈喽大家好,我是咸鱼不知道有没有小伙伴跟我一样,刚开始学习Python的时候都听说过Python是一种解释型语言,因为它在运行的时候会逐行解释并执行,而C++这种是编译型语言不过我今天看到了一篇文章,作者提出Python其实也有编译的过程,解释器会先编译再执行不但如此,作者还认为【......
  • 【re】[HUBUCTF] ezPython --pyc文件
    这道题的附件是一个pyc文件,需要可通过在线网站反编译成py文件在线Pythonpyc文件编译与反编译(lddgo.net)代码逻辑很简单,就是我们读入的东西先base58再base64,最后等于M0hBajFITHVLcWV6R1BOcEM5MTR0R0J3eGZVODV6MTJjZUhGZFNHQw==丢进FromBase64(Base64转换),FromBase58(Base5......
  • python中[::-1]的用法
    在Python编程中,我们经常需要处理和操作数据结构,如列表、字符串和元组等。切片操作是一种强大且常用的方法,通过指定索引范围取出部分数据,不仅提高了代码的可读性,还大大节省了编码时间本文详细介绍Python中的切片操作方法,帮助读者更好地理解和应用。一、切片操作的基本概念1.1......
  • Python 机器学习入门:数据集、数据类型和统计学
    机器学习是通过研究数据和统计信息使计算机学习的过程。机器学习是迈向人工智能(AI)的一步。机器学习是一个分析数据并学会预测结果的程序。数据集在计算机的思维中,数据集是任何数据的集合。它可以是从数组到完整数据库的任何东西。数组的示例:[99,86,87,88,111,86,103,87,94,78,7......
  • Python 机器学习入门:数据集、数据类型和统计学
    机器学习是通过研究数据和统计信息使计算机学习的过程。机器学习是迈向人工智能(AI)的一步。机器学习是一个分析数据并学会预测结果的程序。数据集在计算机的思维中,数据集是任何数据的集合。它可以是从数组到完整数据库的任何东西。数组的示例:[99,86,87,88,111,86,103,87,94,78,......
  • Python51days
      ython_BootStrap1.导入bootstrapBootStrap已经写好的css样式,我们如果想要使用Boostrap:下载boostrap模板在页面上引入bootsrap文件编写HTML时,按照Boostrap的规定来编写+自定制。bootsrap网址:https://www.bootcss.com/ 效果已经自行提供你只需要引入后写入class......