You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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')
关键说明
  1. 逐单元格遍历:通过栅格的行数列数循环,确保每个单元格都被处理,不会因为值相同被合并。
  2. 坐标转换:利用rasterio的transform参数,将栅格行列号转换为实际地理坐标,保证几何的空间位置准确。
  3. 空间参考同步:直接继承原栅格的坐标系(src.crs),避免空间信息丢失。

若你的栅格确实无no_data值,可删除代码中跳过no_data的判断逻辑,此时生成的GeoDataFrame行数会与numpy flatten后的单元格总数完全一致。

内容的提问来源于stack exchange,提问作者tds

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 06:04:54