Python实现TIFF转GPKG:如何保留全部栅格单元格?
问题分析
你遇到的核心问题是:rasterio.features.shapes()函数默认会合并相邻且值相同的栅格单元格,生成单个多边形,而非为每个单元格单独创建几何。这就是为什么numpy flatten得到的单元格总数(350403)远大于GeoDataFrame的行数(343003)——后者是合并后的同值区域数量,而非单个单元格数量。
另外你的代码里还有个明显错误:gpd.GeoDataFrame.from_features(band1)传入的参数不对,应该传入之前生成的results迭代器,但即使修正这个,依然会因为合并逻辑导致数量不匹配。
解决方法:为每个单元格生成独立几何
要保留所有栅格单元格,需要逐个遍历每个单元格,为其生成对应的多边形几何,再构建GeoDataFrame。以下是修正后的代码:
import numpy as np import rasterio from shapely.geometry import Polygon import geopandas as gpd def tiff_to_gpkg(tiff_file: str, gpkg_file: str): ''' Description: - 将TIFF文件转换为GPKG文件,保留所有栅格单元格 Parameters: tiff_file: - 待转换的TIFF文件路径 gpkg_file: - 保存GPKG的文件路径 Returns: None ''' # 读取栅格数据 with rasterio.open(tiff_file) as src: band1 = src.read(1) no_data = src.nodata print(f'no_data值: {no_data}') transform = src.transform rows, cols = band1.shape # 初始化存储几何和值的列表 geometries = [] values = [] # 遍历每个单元格 for row in range(rows): for col in range(cols): val = band1[row, col] # 若存在no_data则跳过,无no_data可删除此判断 if no_data is not None and val == no_data: continue # 计算单元格四个角的地理坐标 x1, y1 = transform * (col, row) x2, y2 = transform * (col + 1, row) x3, y3 = transform * (col + 1, row + 1) x4, y4 = transform * (col, row + 1) # 创建单元格对应的多边形 polygon = Polygon([(x1, y1), (x2, y2), (x3, y3), (x4, y4)]) geometries.append(polygon) values.append(val) # 构建GeoDataFrame并保存 gdf = gpd.GeoDataFrame( {'raster_val': values}, geometry=geometries, crs=src.crs ) gdf.to_file(gpkg_file, driver='GPKG') print(f"生成的GeoDataFrame行数: {len(gdf)}") print(f"栅格总单元格数: {rows * cols}") # 调用示例 # tiff_to_gpkg('input.tif', 'output.gpkg')
关键说明
- 逐单元格遍历:通过栅格的行数列数循环,确保每个单元格都被处理,不会因为值相同被合并。
- 坐标转换:利用
rasterio的transform参数,将栅格行列号转换为实际地理坐标,保证几何的空间位置准确。 - 空间参考同步:直接继承原栅格的坐标系(
src.crs),避免空间信息丢失。
若你的栅格确实无no_data值,可删除代码中跳过no_data的判断逻辑,此时生成的GeoDataFrame行数会与numpy flatten后的单元格总数完全一致。
内容的提问来源于stack exchange,提问作者tds
相关产品推荐
相关产品推荐

