栅格数据分割

为了将一个栅格图像按照指定像元大小进行分割,并保存为单独的TIFF文件,可以使用Python中的rasterio库和numpy库。以下是一个完整的Python程序示例,该程序将栅格图像分割成指定大小的块,并将每个块保存为单独的TIFF文件:

安装依赖库

如果尚未安装依赖库,可以使用以下命令安装:

pip install rasterio numpy

Python程序

import rasterio
import numpy as np
import os

def split_raster(input_file, output_folder, tile_size, nodata_value=None):
    # 打开输入栅格文件
    with rasterio.open(input_file) as src:
        # 获取栅格文件的元数据
        meta = src.meta.copy()
        width = src.width
        height = src.height
        transform = src.transform
        nodata_value = nodata_value if nodata_value is not None else src.nodata
        
        # 计算行数和列数
        rows = np.arange(0, height, tile_size)
        cols = np.arange(0, width, tile_size)
        
        # 创建输出文件夹
        if not os.path.exists(output_folder):
            os.makedirs(output_folder)
        
        # 分割栅格图像
        for i, row_start in enumerate(rows):
            for j, col_start in enumerate(cols):
                row_end = min(row_start + tile_size, height)
                col_end = min(col_start + tile_size, width)
                
                window = rasterio.windows.Window(col_start, row_start, col_end - col_start, row_end - row_start)
                transform_window = rasterio.windows.transform(window, transform)
                
                # 读取窗口内的数据
                data = src.read(window=window)
                
                # 检查数据是否全为nodata
                if np.all(data == nodata_value):
                    print(f"Tile {i}_{j} contains only nodata values, skipping...")
                    continue
                
                meta.update({
                    "height": row_end - row_start,
                    "width": col_end - col_start,
                    "transform": transform_window
                })
                
                output_file = os.path.join(output_folder, f"tile_{i}_{j}.tif")
                with rasterio.open(output_file, 'w', **meta) as dst:
                    dst.write(data)
                
                print(f"Saved {output_file}")

# 示例使用
input_raster = "path_to_your_input_raster.tif"  # 输入栅格图像路径
output_directory = "output_tiles"  # 输出文件夹
tile_size = 256  # 指定像元大小

split_raster(input_raster, output_directory, tile_size)

程序解释

  1. 依赖库导入

    import rasterio
    import numpy as np
    import os
    
  2. 定义 split_raster 函数

    def split_raster(input_file, output_folder, tile_size, nodata_value=None):
    ...
    
    
    • input_file:输入栅格图像的路径。
    • output_folder:输出文件夹路径。
    • tile_size:指定的块大小。
    • nodata_value:指定空值,默认为None。
  3. 打开输入栅格文件

    with rasterio.open(input_file) as src:
        ...
    
  4. 获取栅格文件的元数据

    meta = src.meta.copy()
    width = src.width
    height = src.height
    transform = src.transform
    
  5. 计算行数和列数

    rows = np.arange(0, height, tile_size)
    cols = np.arange(0, width, tile_size)
    
  6. 创建输出文件夹

    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
    
  7. 分割栅格图像并保存

    for i, row_start in enumerate(rows):
            for j, col_start in enumerate(cols):
                row_end = min(row_start + tile_size, height)
                col_end = min(col_start + tile_size, width)
                
                window = rasterio.windows.Window(col_start, row_start, col_end - col_start, row_end - row_start)
                transform_window = rasterio.windows.transform(window, transform)
                
                # 读取窗口内的数据
                data = src.read(window=window)
                
                # 检查数据是否全为nodata
                if np.all(data == nodata_value):
                    print(f"Tile {i}_{j} contains only nodata values, skipping...")
                    continue
                
                meta.update({
                    "height": row_end - row_start,
                    "width": col_end - col_start,
                    "transform": transform_window
                })
                
                output_file = os.path.join(output_folder, f"tile_{i}_{j}.tif")
                with rasterio.open(output_file, 'w', **meta) as dst:
                    dst.write(data)
                
                print(f"Saved {output_file}")
    
  8. 示例使用

    input_raster = "path_to_your_input_raster.tif"
    output_directory = "output_tiles"
    tile_size = 256
    
    split_raster(input_raster, output_directory, tile_size)
    

将路径和文件名替换为实际路径,并运行该程序。它将按照指定的像元大小将输入栅格图像分割并保存为单独的TIFF文件。

三种情况

# ****************
# 1.以下代码按照指定大小分割,包括有空值的块
import rasterio
import numpy as np
import os


def split_raster(input_file, output_folder, tile_size):
    # 打开输入栅格文件
    with rasterio.open(input_file) as src:
        # 获取栅格文件的元数据
        meta = src.meta.copy()
        width = src.width
        height = src.height
        transform = src.transform

        # 计算行数和列数
        rows = np.arange(0, height, tile_size)
        cols = np.arange(0, width, tile_size)

        # 创建输出文件夹
        if not os.path.exists(output_folder):
            os.makedirs(output_folder)

        # 分割栅格图像
        for i, row_start in enumerate(rows):
            for j, col_start in enumerate(cols):
                row_end = min(row_start + tile_size, height)
                col_end = min(col_start + tile_size, width)

                window = rasterio.windows.Window(col_start, row_start, col_end - col_start, row_end - row_start)
                transform_window = rasterio.windows.transform(window, transform)

                meta.update({
                    "height": row_end - row_start,
                    "width": col_end - col_start,
                    "transform": transform_window
                })

                output_file = os.path.join(output_folder, f"tile_{i}_{j}.tif")
                with rasterio.open(output_file, 'w', **meta) as dst:
                    dst.write(src.read(window=window))

                print(f"Saved {output_file}")


# 示例使用
input_raster = r"D:\bali\DEM\DEM_region_UTM111.tif"  # 输入栅格图像路径
output_directory = "output_tiles2"  # 输出文件夹
tile_size = 32  # 指定像元大小

split_raster(input_raster, output_directory, tile_size)
# **************************************
# 2.以下代码是全为空值的块不保存

import rasterio
import numpy as np
import os


def split_raster(input_file, output_folder, tile_size, nodata_value=None):
    # 打开输入栅格文件
    with rasterio.open(input_file) as src:
        # 获取栅格文件的元数据
        meta = src.meta.copy()
        width = src.width
        height = src.height
        transform = src.transform
        nodata_value = nodata_value if nodata_value is not None else src.nodata

        # 计算行数和列数
        rows = np.arange(0, height, tile_size)
        cols = np.arange(0, width, tile_size)

        # 创建输出文件夹
        if not os.path.exists(output_folder):
            os.makedirs(output_folder)

        # 分割栅格图像
        for i, row_start in enumerate(rows):
            for j, col_start in enumerate(cols):
                row_end = min(row_start + tile_size, height)
                col_end = min(col_start + tile_size, width)

                window = rasterio.windows.Window(col_start, row_start, col_end - col_start, row_end - row_start)
                transform_window = rasterio.windows.transform(window, transform)

                # 读取窗口内的数据
                data = src.read(window=window)

                # 检查数据是否全为nodata
                if np.all(data == nodata_value):
                    print(f"Tile {i}_{j} contains only nodata values, skipping...")
                    continue

                meta.update({
                    "height": row_end - row_start,
                    "width": col_end - col_start,
                    "transform": transform_window
                })

                output_file = os.path.join(output_folder, f"tile_{i}_{j}.tif")
                with rasterio.open(output_file, 'w', **meta) as dst:
                    dst.write(data)

                print(f"Saved {output_file}")


# 示例使用
input_raster = r"D:\bali\DEM\DEM_region_UTM111.tif" # 输入栅格图像路径
output_directory = "output_tiles"  # 输出文件夹
tile_size = 16  # 指定像元大小

split_raster(input_raster, output_directory, tile_size)
# ***********************************
# 3.以下代码是一个分割后的影像只要包含空值则不保存
import rasterio
import numpy as np
import os


def split_raster(input_file, output_folder, tile_size, nodata_value=None):
    # 打开输入栅格文件
    with rasterio.open(input_file) as src:
        # 获取栅格文件的元数据
        meta = src.meta.copy()
        width = src.width
        height = src.height
        transform = src.transform
        nodata_value = nodata_value if nodata_value is not None else src.nodata

        # 计算行数和列数
        rows = np.arange(0, height, tile_size)
        cols = np.arange(0, width, tile_size)

        # 创建输出文件夹
        if not os.path.exists(output_folder):
            os.makedirs(output_folder)

        # 分割栅格图像
        for i, row_start in enumerate(rows):
            for j, col_start in enumerate(cols):
                row_end = min(row_start + tile_size, height)
                col_end = min(col_start + tile_size, width)

                window = rasterio.windows.Window(col_start, row_start, col_end - col_start, row_end - row_start)
                transform_window = rasterio.windows.transform(window, transform)

                # 读取窗口内的数据
                data = src.read(window=window)

                # 检查数据中是否包含任何nodata值
                if nodata_value is not None and np.any(data == nodata_value):
                    print(f"Tile {i}_{j} contains nodata values, skipping...")
                    continue

                meta.update({
                    "height": row_end - row_start,
                    "width": col_end - col_start,
                    "transform": transform_window
                })

                output_file = os.path.join(output_folder, f"tile_{i}_{j}.tif")
                with rasterio.open(output_file, 'w', **meta) as dst:
                    dst.write(data)

                print(f"Saved {output_file}")


# 示例使用
input_raster = r"D:\bali\DEM\DEM_region_UTM111.tif"  # 输入栅格图像路径
output_directory = "output_tiles"  # 输出文件夹
tile_size = 8  # 指定像元大小

split_raster(input_raster, output_directory, tile_size)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值