【Python&RS】基于Rasterio库裁剪栅格数据&压缩栅格影像

        之前分享过【Python&RS】Rasterio库安装+基础函数使用教程,大家有兴趣的可以去看看。由于最近有涉及到栅格裁剪和压缩的问题,所以研究了一下今天和大家分享分享。

原创作者:RS迷途小书童

博客地址:https://blog.csdn.net/m0_56729804?type=blog

1 需要的库

import os
import rasterio
import geopandas as gpd
from rasterio.mask import mask
from rasterio.plot import show
from rasterio.windows import Window, from_bounds
from shapely.geometry import Point, Polygon, box, mapping, LineString

2 自定义矩形框裁剪

        这里的矩形可以自己选择大小,当然也可以通过读取矢量的空间范围去裁剪。同时代码中还加入了压缩参数。

def compress_tif(tif_path, output_file):
    with rasterio.open(tif_path) as src:
        transform = src.transform
        # minx, miny, maxx, maxy = geometry1.bounds(要素的地理字段)
        expanded_bbox = box(minx=0, miny=0, maxx=100, maxy=100)  # 创建一个新的扩展后的边界框(Shapely box)
        window = from_bounds(expanded_bbox.bounds[0], expanded_bbox.bounds[1],
                             expanded_bbox.bounds[2], expanded_bbox.bounds[3],
                             transform=transform)  # 将Shapely几何对象转换为rasterio可以理解的边界
        clipped = src.read(window=window)  # 读取并裁剪TIFF数据

        out_meta = src.meta.copy()
        out_meta.update({"driver": "GTiff", "compress": 'lzw'})  # 更新元数据,rle,lzw等
        del src
    with rasterio.open(output_file, 'w', **out_meta) as dest:  # 写入裁剪后的TIFF文件
        dest.write(clipped)
# 压缩和裁剪栅格数据
def compress_tif(tif_path, output_file):
    with rasterio.open(tif_path) as src:
        transform = src.transform
        # minx, miny, maxx, maxy = geometry1.bounds(要素的地理字段)
        # expanded_bbox = box(minx=0, miny=0, maxx=100, maxy=100)  # 创建一个新的扩展后的边界框(Shapely box)
        # window = from_bounds(expanded_bbox.bounds[0], expanded_bbox.bounds[1],
        #                      expanded_bbox.bounds[2], expanded_bbox.bounds[3],
        #                      transform=transform)  # 将Shapely几何对象转换为rasterio可以理解的边界
        window = from_bounds(11, 2, 3, 4, transform=transform)
        clipped = src.read(window=window)  # 读取并裁剪TIFF数据

        out_meta = src.meta.copy()
        out_meta.update({"driver": "GTiff", "height": window.height, "width": window.width,
                         "transform": rasterio.windows.transform(window, transform), "compress": 'lzw'})
        # 更新元数据,rle,lzw等
        del src
    with rasterio.open(output_file, 'w', **out_meta) as dest:  # 写入裁剪后的TIFF文件
        dest.write(clipped)

3 使用矢量要素裁剪

        这里使用到了geopandas库用来读取每个要素的空间范围。

def clip_raster_from_features(vector_file=r"彭俊喜/1.shp", raster_file=r"彭俊喜/1.tif"):
    """
    :param vector_file: 输入需要裁剪的面矢量(多面)
    :param raster_file: 输入需要裁剪的影像
    :return: None
    """
    # 读取面矢量数据
    gdf = gpd.read_file(vector_file)
    # 循环遍历面矢量中的每个面要素
    for index, row in gdf.iterrows():
        # 获取当前面要素的几何形状
        geometry1 = row.geometry
        # 确保面要素不是空的
        if geometry1.is_empty:
            print(f"Skipping empty geometry for feature {index}")
            continue
            # 打开影像文件
        with rasterio.open(raster_file) as src:
            # 将面要素的边界转换为shapely的box对象
            geometry_bounds = box(*geometry1.bounds)
            # 将rasterio的bounds转换为shapely的box对象
            src_bounds = box(*src.bounds)
            # 检查面要素的边界是否与影像的边界相交
            if not geometry_bounds.intersects(src_bounds):
                print(f"Skipping feature {index} as it does not intersect with the raster.")
                continue
                # 转换几何形状为Rasterio可以理解的格式
            geom_for_rasterio = mapping(geometry1)
            # 使用面要素裁剪影像
            try:
                out_image, out_transform = mask(src, [geom_for_rasterio], crop=True)
            except ValueError as e:
                print(f"Error clipping feature {index}: {e}")
                continue
                # 检查是否成功裁剪出影像
            if out_image is None:
                print(f"No data was clipped for feature {index}. Skipping.")
                continue
                # 为裁剪后的影像设置输出路径和文件名
            output_file = f'clipped_image_{index}.tif'
            output_path = os.path.join(r'Z:\Shanghai Metro Automatic Identification System\Data Source\weigui\1',
                                       output_file)
            # 创建输出文件,并写入裁剪后的影像数据
            dtypes = [src.dtypes[i] for i in range(src.count)]  # 确保数据类型列表与波段数量匹配
            # 假设所有波段的数据类型都是相同的,并且你想要保持与输入影像相同的数据类型
            dtype = src.dtypes[0]  # 获取第一个波段的数据类型
            # 使用这个数据类型打开输出文件
            with rasterio.open(output_path, 'w', driver='GTiff', height=out_image.shape[1],
                               width=out_image.shape[2], count=src.count, dtype=dtype,
                               crs=src.crs, transform=out_transform) as dest:
                dest.write(out_image)
            print(f'Clipped image {output_file} has been saved.')
    print('All features have been processed.')
python2.7栅格数据批量转换投影:ProjectRaster_management (in_raster, out_raster, out_coor_system, {resampling_type}, {cell_size}, {geographic_transform}, {Registration_Point}, {in_coor_system}) in_raster 输入栅格数据集。Mosaic Layer; Raster Layer out_raster 要创建的输出栅格数据集。以文件格式存储栅格数据集时,需要指定文件扩展名,具体如下:.bil - Esri BIL, .bip - Esri BIP, .bmp - BMP, .bsq - Esri BSQ, .dat - ENVI DAT,.gif - GIF,.img - ERDAS IMAGINE,.jpg - JPEG,.jp2 - JPEG 2000,.png - PNG,.tif - TIFF,无扩展名 - Esri Grid,以地理数据形式存储栅格数据集时,不应向栅格数据集的名称添加文件扩展名。 将栅格数据集存储到 JPEG 文件、JPEG 2000 文件、TIFF 文件或地理数据时,可以指定压缩类型和压缩质量。 Raster Dataset out_coor_system 输入栅格待投影到的目标坐标系。默认值将基于“输出坐标系”环境设置进行设定。该参数的有效值是扩展名为 .prj 的文件。现有要素类、要素数据集、栅格目录(基本上包含了与坐标系相关的所有内容)。坐标系的字符串表示。要生成此类较长的字符串,可向模型构建器添加一个坐标系变量,并根据需要设置该变量的值,然后将模型导出到 Python 脚本。 Coordinate System resampling_type (可选) 要使用的重采样算法。默认设置为 NEAREST。 NEAREST —最邻近分配法 BILINEAR —双线性插值法 CUBIC —三次卷积插值法 MAJORITY —众数重采样法 NEAREST 和 MAJORITY 选项用于分类数据,如土地利用分类。NEAREST 选项是默认设置,因为它是最快的插值法,同时也因为它不会更改像元值。请勿对连续数据(如高程表面)使用 NEAREST 或 MAJORITY。BILINEAR 选项和 CUBIC 选项最适用于连续数据。不推荐对分类数据使用 BILINEAR 或者 CUBIC,因为像元值可能被更改。 cell_size (可选) 新栅格数据集的像元大小。默认像元大小为所选栅格数据集的像元大小。 Cell Size XY geographic_transform (可选) 在两个地理坐标系或基准面之间实现变换的方法。当输入和输出坐标系的基准面相同时,地理(坐标)变换为可选参数。如果输入和输出基准面不同,则必须指定地理(坐标)变换。 有关各个受支持的地理(基准面)变换的详细信息,请参阅位于 ArcGIS 安装目录的 \Documentation 文件夹下的 geographic_transformations.pdf 文件。 Registration_Point(可选)用于对齐像素的 x 和 y 坐标(位于输出空间中)。配准点的工作原理与捕捉栅格的概念类似。通过配准点可指定用于定位输出像元的原点,而不是仅将输出捕捉到现有栅格像元。所有输出像元与该点之间必须间隔一个像元。该点的坐标不必位于一角,也不必落入栅格数据集中。捕捉栅格环境设置参数将优先于 Registration_Point 参数。因此,如果您要设置配准点,请确保尚未设置捕捉栅格。 in_coor_system (可选) 输入栅格数据集的坐标系。Coordinate System
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RS迷途小书童

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值