为了将一个栅格图像按照指定像元大小进行分割,并保存为单独的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)
程序解释
-
依赖库导入:
import rasterio import numpy as np import os
-
定义
split_raster
函数:def split_raster(input_file, output_folder, tile_size, nodata_value=None): ...
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
-
计算行数和列数:
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)
将路径和文件名替换为实际路径,并运行该程序。它将按照指定的像元大小将输入栅格图像分割并保存为单独的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)