简介:本资源为适配 PostgreSQL 17 的 PostGIS 3.5.0 64 位安装包,面向需要在关系型数据库中处理空间数据的 GIS 开发者、后端工程师及地理信息相关专业学生。PostGIS 在 PostgreSQL 基础上扩展了空间对象类型与空间函数,支持空间索引、空间聚合、空间连接及地理空间距离、面积、路径分析等操作,可广泛应用于城市规划、交通管理、环境监测、物流配送等场景。压缩包共 1317 个文件,约 130.69MB,以 933 个 sql 脚本、79 个 dll 动态库、75 个 csv 数据文件及 50 个 tif 栅格文件为主,另含 control 扩展定义、json/xml 配置、exe 工具与多种坐标系参数文件,覆盖扩展安装、数据导入与坐标转换等环节。目前已有 192 人学习下载。借助该安装包,读者可将 PostGIS 集成到 PostgreSQL 17 中,快速获得点、线、面等空间数据的管理与分析能力,为 GIS 项目搭建稳定的空间数据存储与处理环境。
1. postgis-bundle-pg17-3.5.0x64.zip:一个压缩包背后要跑通的三件事
拿到postgis-bundle-pg17-3.5.0x64.zip这个文件名,很多人第一反应是「解压、装、完事」。真到生产环境里翻车的,恰恰是这一步。这个包名其实把三件事压在一起:PostgreSQL 17 的主版本、PostGIS 3.5.0 的空间扩展、以及 x64 的 Windows 二进制分发形态。它解决的是「不想自己编译 GDAL、GEOS、PROJ 那一长串依赖,直接拿一份能跑的 PostGIS」这个诉求,适合做 GIS 后端、做空间数据入库、或者要在内网离线环境里搭一套空间数据库的工程师。但 zip 只是分发外壳,真正决定你能不能跑起来的,是版本对齐、扩展注册和依赖路径这三件事。下面按「先搞清包里是什么、再动手装、最后排坑」的顺序讲透。
2. 先搞懂 bundle 包里到底装了什么:pg17 与 3.5.0 的版本对齐逻辑
PostGIS 不是一个能独立运行的程序,它是挂在 PostgreSQL 进程里的扩展。所以postgis-bundle-pg17-3.5.0x64.zip这个名字里,pg17和3.5.0是两个必须同时成立的约束:前者决定你机器上得先有 PostgreSQL 17,后者决定扩展的 SQL 定义和动态库版本。bundle 的意思是把 PostGIS 运行所需的动态库(postgis-3.dll、libgeos、libproj、libgdal等)一起打包,省去你逐个找依赖的麻烦。
2.1 为什么必须是 pg17 而不是 pg16 或 pg18
PostgreSQL 的大版本之间,扩展的 ABI(应用二进制接口)并不保证兼容。PostGIS 编译时会链接到特定大版本的postgres.exe导出符号,pg17的包拿到 pg16 上,CREATE EXTENSION postgis大概率报could not load library或者直接让服务起不来。反过来,pg18 上跑 pg17 的包,同样会因为内部结构体布局变化而崩。所以第一件事是确认你本机的 PostgreSQL 主版本号,命令行里执行:
postgres --version # 期望输出类似:postgres (PostgreSQL) 17.x如果输出是 16 或 18,别硬上,去换对应版本的 bundle。这一步没有后悔药,版本错了后面全是玄学报错。
2.2 3.5.0 这个版本号意味着什么
PostGIS 3.5 系列在 3.x 里属于较新的稳定线,SQL API 层面和 3.4 基本兼容,但底层 GEOS、PROJ 的版本要求会更高。bundle 包已经把匹配的 GEOS/PROJ 打进去了,你不需要单独装。需要留意的是:如果你之前装过旧版 PostGIS,升级到 3.5.0 时,数据库里已有的扩展要先ALTER EXTENSION postgis UPDATE,而不是直接覆盖文件。版本号里的x64只说明这是 64 位 Windows 二进制,32 位系统直接放弃。
2.3 zip 这种分发形态的取舍
用 zip 而不是 exe 安装器,好处是绿色、可控、方便内网离线搬运;代价是没有自动写注册表、没有自动配 PATH、没有自动建扩展。也就是说,解压只是第一步,后面「把 dll 放到 PostgreSQL 能找到的目录」「把扩展 SQL 注册进 share 目录」这些活都得自己干。理解了这一点,就不会指望双击一下就完事。
3. 在 Windows 上把 bundle 装进 PostgreSQL 17 的完整步骤
这一章是能直接抄作业的部分。前提:你已经装好 PostgreSQL 17(x64),并且知道它的安装目录,下面用%PGBASE%代指,比如C:\Program Files\PostgreSQL\17。
3.1 解压与目录结构确认
先把 zip 解到一个临时目录,看清里面的结构。常见布局是bin/、lib/、share/extension/三块。
# 假设解压到 D:\tmp\postgis-bundle # 查看目录结构 dir /s /b D:\tmp\postgis-bundle你会看到类似lib\postgis-3.dll、share\extension\postgis--3.5.0.sql、bin\shp2pgsql.exe这些文件。lib下的 dll 是运行时依赖,share\extension下的 SQL 是扩展定义,bin下是命令行工具。三者缺一,扩展都建不起来。
3.2 把文件复制到 PostgreSQL 对应目录
这一步是核心,复制错位置是最常见的翻车点。
# 复制动态库到 PostgreSQL 的 lib 目录 xcopy /Y D:\tmp\postgis-bundle\lib\*.dll "%PGBASE%\lib\" # 复制扩展定义到 share\extension xcopy /Y /E D:\tmp\postgis-bundle\share\extension\* "%PGBASE%\share\extension\" # 复制命令行工具到 bin(可选,但建议) xcopy /Y D:\tmp\postgis-bundle\bin\*.exe "%PGBASE%\bin\"逻辑说明:PostgreSQL 加载扩展时,会去%PGBASE%\lib找postgis-3.dll,去%PGBASE%\share\extension找postgis.control和对应的 SQL 文件。这两个路径是编译时写死的,不能随便改。参数上/Y是覆盖不提示,/E是连子目录一起复制。复制完最好核对一下postgis.control里的default_version是不是3.5.0。
3.3 在数据库里注册扩展
文件到位后,连上目标数据库执行建扩展语句。
-- 连接到你的业务库后执行 CREATE EXTENSION postgis; -- 验证版本 SELECT PostGIS_Full_Version();如果返回一串包含POSTGIS="3.5.0"和GEOS、PROJ版本的信息,说明装成了。CREATE EXTENSION这一步做的是把share\extension里的 SQL 脚本跑一遍,在库里创建spatial_ref_sys等系统表和几百个函数。参数上不需要额外指定,PostgreSQL 会按postgis.control里的默认版本加载。
3.4 用 shp2pgsql 验证工具链是否打通
光建扩展还不够,实际干活要用到导入工具。拿一个 shapefile 试一下:
shp2pgsql -s 4326 -I D:\data\roads.shp public.roads | psql -U postgres -d gisdb-s 4326指定源数据 SRID,-I表示在几何列上建 GiST 索引。这条命令能跑通,说明bin下的工具和lib下的 dll 都链接正常。如果报找不到libgeos,回到 3.2 检查 dll 是否复制全。
4. 装完跑不起来?postgis 安装失败的排查清单
这一章专门收「装完报错」的场景。下面 5 条是我自己踩过、也帮别人定位过的典型问题,按「现象 → 原因 → 解决」写。
4.1 现象:CREATE EXTENSION 报 could not load library "postgis-3.dll"
原因:dll 没复制到%PGBASE%\lib,或者复制了但缺少它依赖的libgeos、libproj等同目录 dll。Windows 加载 dll 时会在同目录找依赖,缺一个就整体失败。
解决:确认%PGBASE%\lib下postgis-3.dll和 bundle 里lib目录的所有 dll 都在。可以用dumpbin /dependents postgis-3.dll看它依赖哪些库,逐个核对。
4.2 现象:报 could not open extension control file
原因:share\extension下没有postgis.control,或者复制时路径多套了一层目录。
解决:检查%PGBASE%\share\extension\postgis.control是否存在。如果复制成了share\extension\extension\postgis.control,把里层文件挪上来。
4.3 现象:服务启动直接失败,事件日志报模块加载错误
原因:把 pg17 的 dll 复制进了 pg16 或 pg18 的目录,ABI 不匹配导致postgres.exe启动时崩溃。
解决:核对postgres --version,换对应版本的 bundle,别混用。
4.4 现象:PostGIS_Full_Version 里 GEOS 版本是旧的
原因:系统 PATH 里存在另一份旧版 GEOS dll,被优先加载了。
解决:把%PGBASE%\lib放到 PATH 最前面,或者干脆把旧版 GEOS 从 PATH 里移除。这是典型的「玄学」问题,版本号对不上但又不报错。
4.5 现象:升级后旧函数报错,提示 function does not exist
原因:只覆盖了文件,没在库里执行扩展升级。
解决:连库执行ALTER EXTENSION postgis UPDATE TO '3.5.0';,让 SQL 定义同步到新版本。
5. 让这套 bundle 真正进生产的三个进阶习惯
装通只是起点。要在生产里稳住,我一般会做三件事。第一,把 bundle 里的 dll 和 SQL 按版本号归档,别直接覆盖,出问题能回滚。第二,用pg_dump备份时带上--extension相关处理,恢复时先建扩展再导数据,避免顺序错乱。第三,把postgis.control里的版本和实际 dll 版本做一次脚本校验,写进部署流程。
下面这个小脚本可以放在部署后跑,快速确认版本一致性:
# 校验 control 文件声明的版本与 dll 实际版本 findstr /C:"default_version" "%PGBASE%\share\extension\postgis.control" # 再用 psql 查实际加载版本 psql -U postgres -d gisdb -c "SELECT extversion FROM pg_extension WHERE extname='postgis';"两处输出一致,才算真正装对。不一致就说明文件覆盖和库内注册脱节了,这在批量部署时特别容易发生。
| 检查项 | 期望值 | 不一致时的动作 |
|---|---|---|
| postgres 主版本 | 17.x | 换对应 bundle |
| control 默认版本 | 3.5.0 | 重新复制 share 目录 |
| 库内 extversion | 3.5.0 | 执行 ALTER EXTENSION UPDATE |
| GEOS/PROJ 版本 | 与 bundle 一致 | 清理 PATH 旧库 |
我自己的习惯是:每次拿到一个新的 bundle,先在测试库上完整走一遍「解压 → 复制 → 建扩展 → 导一个 shp → 查版本」,全绿了再上生产。这套流程看着笨,但省下的排查时间远超那几分钟。希望帮到你。
本文还有配套的精品资源,点击获取