【应用实践】PostGIS 影像文件导出五种方案详解,实操干货无盲区

📅 2026/6/26 4:24:35
【应用实践】PostGIS 影像文件导出五种方案详解,实操干货无盲区
PostGIS 中的栅格数据以 raster 数据类型存储在表中无法直接被GIS或者遥感影像处理软件读取本文介绍五种常用的将 PostGIS 栅格表数据导出到文件方法全是干货在具体实践中可以根据需要应用。方法一、服务器端 lo_export 导出该方案是服务器端导出标准 GeoTIFF 的方式导出栅格文件可直接被 QGIS/ArcGIS/ENVI 等软件打开具体操作步骤如下:首先启用 GDAL 支持若已开启可忽略setpostgis.gdal_enabled_driversENABLE_ALLsetpostgis.enable_outdb_rastersTrue为了保障文件读写权限问题可以创建好目录# 创建导出目录mkdir-p/opt/pg_export# 授予 postgres 用户目录所有权chownpostgres:postgres /opt/pg_export# 设置目录读写权限chmod755/opt/pg_export最后执行导出栅格数据-- 1. 将栅格转为TIFF二进制并生成大对象返回OID存入变量SELECTlo_from_bytea(0,ST_AsTIFF(rast,LZW))ASlo_oidFROMwuhan_landcover_2024WHERErid1-- 返回文件oid标识每次执行返回值不同50485-- 2. 将大对象导出为纯净TIFF文件目录需保证postgres用户可写SELECTlo_export(50485,/opt/pg_export/output_single.tif);-- 3. 清理临时大对象释放资源必做SELECTlo_unlink(50485);注意事项:gdal驱动配置要开启。文件路径确保输出文件路径存在且具有写权限。方法二、psql xxd 原生方式该方案本质是直接提取 PostGIS 生成的标准 GeoTIFF 二进制流全程不经过 PostgreSQL 的 COPY 格式封装从根源避免了 PG 私有格式头导致的文件无法识别问题,该方法较为简单。示例脚本如下psql-dgisdata-Upostgres-t-A-cSELECT encode(ST_AsTIFF(ST_Union(rast), LZW), hex) FROM wuhan_landcover_2024|xxd-r-p/opt/pg_export/wuhan_landcover_2024_full.tifpsql参数这里不做详解xdd命令用于将文件或数据转换为十六进制格式显示类似于十六进制查看器关于xdd命令详解可以查询其他资料。xxd-r-p-r反向模式将十六进制文本转换为二进制 -p纯文本模式输入为连续十六进制字符无地址列、ASCII 列完美匹配 psql-t-A的输出格式注意事项:需要先安装xdd命令根据具体系统环境进行安装。CentOS/RHEL 系统安装如下sudoyuminstallvim-common方法三、GDAL 工具 gdal_translategdal_translate 是 GDAL 工具集的核心栅格转换命令也是从 PostGIS 导出标准 GeoTIFF 的生产级首选方案在QGIS的工具中实际上也是用的此命令。相比 SQL 方式它自动处理瓦片合并、内存优化更完善、输出原生标准 GeoTIFF无格式头兼容问题导出后可直接被 QGIS/ArcGIS 读取尤其适合 GB 级大栅格场景。后续也会单独一个章节来介绍该工具该方案较为灵活也比较简单。gdal_translate\PG:dbnamegisdata userpostgres passwordgisdata tablewuhan_landcover_2024 mode2\/opt/pg_export/export.tif\-coCOMPRESSLZW导出如图所示注意事项:此方法需要在安装 GDAL 的时候支持 Postgis Raster 驱动。方法四、连接 QGIS 客户端导出QGIS 连接数据库:在QGIS中连接PostGIS数据库导出文件:连接数据库之后可以看到数据库中的各个表然后选择右键 - Export Layer - To File…根据导出的需要填写配置信息注意事项:该方法比较简单只需要软件操作不需要任何代码方法五、编写Python代码导出该方法核心原理是通过 SQL 函数 ST_Union 合并分块栅格 ST_AsTIFF 将栅格转为 TIFF 二进制流再用 Python 写入文件。关键核心代码示例如下importpsycopg2frompsycopg2importsql# -------------------------- 1. 配置参数修改为你的实际信息------------DB_CONFIG{host:localhost,# 数据库地址port:5432,# 端口dbname:gisdata,# 数据库名user:postgres,# 用户名password:pwd,# 密码raster_table:raster_test,# 栅格数据表名raster_column:rast,# 栅格列名PostGIS默认列名rastoutput_tif:output.tif# 导出的TIFF文件路径}# -------------------------- 2. 核心导出函数 --------------------------defexport_postgis_raster_to_tiff():connNonetry:# 1. 连接 PostGIS 数据库connpsycopg2.connect(**DB_CONFIG)curconn.cursor()print(数据库连接成功)# 2. 核心SQL合并分块栅格 转为TIFF二进制流# ST_Union合并PostGIS分块存储的栅格# ST_AsTIFF栅格转TIFF参数LZW为无损压缩可选DEFLATE/无压缩sql_querysql.SQL( SELECT ST_AsTIFF(ST_Union({raster_col}), LZW) AS tiff_bytes FROM {table} -- 可选添加筛选条件如范围、属性过滤 -- WHERE geom ST_MakeEnvelope(xmin, ymin, xmax, ymax, 4326) ).format(raster_colsql.Identifier(DB_CONFIG[raster_column]),tablesql.Identifier(DB_CONFIG[raster_table]))# 3. 执行查询获取TIFF二进制数据cur.execute(sql_query)tiff_binarycur.fetchone()[0]# 获取二进制流# 4. 写入本地TIFF文件二进制写入模式withopen(DB_CONFIG[output_tif],wb)asf:f.write(tiff_binary)print(f栅格导出成功文件路径{DB_CONFIG[output_tif]})exceptExceptionase:print(f导出失败{str(e)})finally:# 关闭数据库连接ifconn:cur.close()conn.close()print(数据库连接已关闭)# -------------------------- 3. 执行导出 --------------------------if__name____main__:export_postgis_raster_to_tiff()核心代码关键点解析:数据库连接使用 psycopg2 连接 PostgreSQL/PostGIS是 Python 操作 PostGIS 最标准的库。核心 SQL 函数ST_Union({raster_col})PostGIS 栅格一般采用分块存储合并后才能得到完整栅格ST_AsTIFF(栅格对象, 压缩参数)将栅格直接转为 TIFF 二进制数据支持压缩优化LZW无损压缩推荐文件小、速度快DEFLATE高压缩比留空无压缩二进制数据处理查询返回的是 TIFF 文件的原始二进制流直接用 wb二进制写入模式保存为 .tif 即可无需额外解码。