简介:postgis-bundle-pg12-3.4.2x64.zip 是面向 PostgreSQL 12 用户的 PostGIS 3.4.2 空间数据库扩展安装包,适用于从事地理信息系统开发、空间数据分析与城市规划、环境监测、交通导航等场景的开发者与 GIS 工程师。PostGIS 在对象关系型数据库之上增加空间数据存储与管理能力,兼容 OGC 简单特征访问标准,可与 QGIS、GRASS GIS、uDig 等软件协同工作,支持二维至四维空间对象、空间索引、坐标投影转换以及 shapefile、GeoJSON、KML、GPX 等格式读写。压缩包共 1281 个文件,约 129.44MB,以 895 个 sql 脚本、78 个 dll 动态库、74 个 csv 数据文件为主,另含 tif 栅格、control 扩展控制文件、pl 脚本及 xml、json 配置等,覆盖扩展注册、数据装载与示例数据等模块。目前已有 112 人学习下载,适合需要快速部署空间数据库、研究扩展目录结构或搭建 GIS 实验环境的读者参考。
1. postgis-bundle-pg12-3.4.2x64.zip 到底是什么:一次把 Windows 上的空间数据库装明白
如果你在 Windows 上装过 PostGIS,大概率经历过这种场景:PostgreSQL 12 装好了,pgAdmin 能连上,结果一执行CREATE EXTENSION postgis;就报could not open extension control file,或者干脆提示找不到postgis-3.dll。搜「postgis安装失败」,出来的答案一半让你去改 PATH,一半让你重装 PostgreSQL,照着做还是不行。postgis-bundle-pg12-3.4.2x64.zip这个文件名其实已经把答案写清楚了:它是给 PostgreSQL 12、64 位 Windows 用的 PostGIS 3.4.2 打包版本,bundle 的意思是「捆绑包」,里面不只有 PostGIS 扩展本身,还带了 GEOS、PROJ、GDAL 这些空间计算依赖库。换句话说,它解决的核心问题就是:让你不用自己编译 GDAL 和 PROJ,直接把空间能力挂到已有的 PG12 上。这篇内容适合两类人:一是在 Windows 上被 PostGIS 依赖折腾过的后端或 GIS 开发,二是需要在本机或内网快速搭一套空间数据库做验证的数据工程。接下来我会按「先搞懂包里有什么、再动手装、最后排错」的顺序讲透。
2. 拆开这个 bundle:目录结构、依赖关系和版本匹配逻辑
2.1 bundle 和普通 PostGIS 安装包的区别在哪
很多人第一次看到postgis-bundle会以为是某个第三方魔改版,其实它是 PostGIS 官方在 Windows 上的一种分发形式。普通安装方式要么用 StackBuilder(依赖网络、版本受限于官方列表),要么自己下源码编译(Windows 上编译 GDAL 是出了名的血泪经验)。bundle 包把编译好的二进制、依赖 DLL、SQL 脚本、扩展控制文件全部塞进一个压缩包,解压后按目录对应复制到 PostgreSQL 安装目录即可。
它和「PostGIS 单独安装包」最大的区别在于依赖处理。PostGIS 本身不是一个孤立扩展,它依赖三个底层库:
| 依赖库 | 作用 | 缺失时的典型报错 |
|---|---|---|
| GEOS | 几何运算(相交、缓冲、拓扑) | could not load library postgis-3.dll |
| PROJ | 坐标投影与转换 | transform: couldn't project point |
| GDAL | 栅格与多格式数据读写 | rt_raster_from_gdal_dataset相关错误 |
普通安装包往往只给 PostGIS 自己的文件,依赖要你另外配。bundle 把这些一起打包,所以体积会明显大一些,但换来的是「复制完就能用」。这也是为什么搜 postgis 安装失败的人,最后大多被建议换成 bundle 版本。
2.2 文件名里的 pg12、3.4.2、x64 分别约束了什么
postgis-bundle-pg12-3.4.2x64.zip这个名字不是随便起的,每个字段都是硬约束,装错一个就失败:
- pg12:对应 PostgreSQL 12 的大版本。PostGIS 的二进制和 PostgreSQL 的 ABI 是绑定的,PG12 编译出来的扩展不能直接丢进 PG13/14/15,反之亦然。你本机是 PG12.x 的任意小版本(12.0 到 12.22)都可以用,但跨大版本不行。
- 3.4.2:PostGIS 的版本号。3.4 系列要求 PostgreSQL 最低 12,所以这个组合是官方支持的。3.4.2 属于 3.4 的补丁版本,修了一些几何解析和栅格相关的 bug。
- x64:64 位。必须和你的 PostgreSQL 位数一致。如果你装的是 32 位 PG(现在很少见),这个包用不了。
提示:确认自己 PostgreSQL 版本和位数的命令是
SELECT version();,输出里会带64-bit字样。别靠安装目录名猜。
2.3 解压后你会看到哪些目录
把 zip 解压到一个临时目录,典型结构是这样的(不同小版本目录名可能略有差异,但层级一致):
postgis-bundle-pg12-3.4.2x64/ ├── bin/ # postgis-3.dll、依赖 DLL、shp2pgsql 等命令行工具 ├── lib/ # 扩展的 .so/.dll 运行库 ├── share/ │ └── extension/ # postgis.control、postgis--3.4.2.sql 等扩展定义 └── utils/ # 一些辅助脚本这三个目录分别对应 PostgreSQL 安装目录下的bin、lib、share/extension。安装的本质就是「把 bundle 里的文件按对应关系复制过去」。理解这一点,后面所有步骤都不会迷路。
3. 在 Windows 上把 PostGIS 3.4.2 挂到 PG12:复制、建扩展、验证三步走
3.1 安装前必须确认的三件事
动手之前先花两分钟确认环境,能省掉后面一半的排错时间:
- PostgreSQL 服务能正常启动,用 pgAdmin 或
psql能连上。 - PostgreSQL 安装目录可写,因为你要往
bin、lib、share/extension里复制文件。默认装在C:\Program Files\PostgreSQL\12的话,复制时可能需要管理员权限。 - 停掉 PostgreSQL 服务再复制 DLL。Windows 上正在运行的进程会锁住
postgis-3.dll,不停服务复制会提示文件被占用。
停服务的命令(管理员 PowerShell):
# 停止 PostgreSQL 12 服务,服务名通常是 postgresql-x64-12 net stop postgresql-x64-12 # 复制完成后重新启动 net start postgresql-x64-12服务名不确定的话,用services.msc打开服务列表,找带 PostgreSQL 的那一项,看它的「服务名称」列。
3.2 按目录复制文件:bin、lib、share/extension 各放什么
假设 PostgreSQL 装在C:\Program Files\PostgreSQL\12,bundle 解压在D:\postgis-bundle,复制逻辑如下:
# 1. 复制 DLL 和命令行工具到 PG 的 bin 目录 # postgis-3.dll、libgeos、libproj、gdal 相关 DLL 都在这里 xcopy /Y /E "D:\postgis-bundle\bin\*" "C:\Program Files\PostgreSQL\12\bin\" # 2. 复制运行库到 lib 目录 xcopy /Y /E "D:\postgis-bundle\lib\*" "C:\Program Files\PostgreSQL\12\lib\" # 3. 复制扩展定义文件到 share\extension # 这一步最关键,postgis.control 和 postgis--3.4.2.sql 都在这里 xcopy /Y /E "D:\postgis-bundle\share\extension\*" "C:\Program Files\PostgreSQL\12\share\extension\"xcopy的/Y表示覆盖时不询问,/E表示连子目录一起复制。三条命令分别对应「可执行文件」「运行库」「扩展元数据」,缺任何一条都会导致CREATE EXTENSION失败。
复制完成后启动服务:
net start postgresql-x64-12注意:如果你的 PostgreSQL 是通过 EDB 安装器装的,
share\extension目录里可能已经有一些其他扩展的 control 文件,复制时不要删掉原有的,只做覆盖和新增。
3.3 建扩展并验证:从 CREATE EXTENSION 到第一个空间查询
服务起来后,用 psql 或 pgAdmin 连上你要启用空间能力的数据库(建议新建一个测试库,别直接在生产库上试):
-- 连接到目标数据库后执行 CREATE EXTENSION postgis; -- 验证版本,应该返回 3.4.2 相关字样 SELECT PostGIS_Full_Version(); -- 验证几何运算是否正常(依赖 GEOS) SELECT ST_Area(ST_Buffer(ST_Point(0,0), 1)); -- 验证投影转换是否正常(依赖 PROJ) SELECT ST_AsText(ST_Transform(ST_SetSRID(ST_Point(116.4, 39.9), 4326), 3857));PostGIS_Full_Version()会一次性输出 PostGIS、GEOS、PROJ、GDAL 的版本,这是判断依赖有没有装全的最快方式。如果它返回了完整信息,说明 bundle 里的依赖都被正确加载了。ST_Buffer测的是 GEOS,ST_Transform测的是 PROJ,两个都通过,基本可以确认安装成功。
如果还想验证栅格能力(GDAL),可以再跑:
CREATE EXTENSION postgis_raster; SELECT ST_AsText(ST_Envelope(ST_MakeEmptyRaster(10, 10, 0, 0, 1, 1, 0, 0, 4326)));postgis_raster在 PostGIS 3.x 里是独立扩展,需要单独创建,但它依赖的 GDAL 库已经在 bundle 里了。
4. postgis安装失败排查:五类高频报错的现象、原因和解决
4.1 报错 could not open extension control file
现象:执行CREATE EXTENSION postgis;时提示could not open extension control file ".../share/extension/postgis.control": No such file or directory。
原因:share/extension目录里没有postgis.control,说明第 3.2 步的第三条复制命令没执行,或者复制到了错误的 PostgreSQL 目录(比如机器上装了多个 PG 版本,复制到了另一个版本下)。
解决:确认当前连接的 PostgreSQL 用的是哪个安装目录。用SHOW data_directory;看数据目录,反推安装目录,然后把postgis.control和postgis--3.4.2.sql复制到正确的share/extension下。复制后不需要重启服务,重新执行CREATE EXTENSION即可。
4.2 报错 could not load library postgis-3.dll
现象:CREATE EXTENSION时报could not load library "C:/Program Files/PostgreSQL/12/lib/postgis-3.dll": The specified module could not be found。
原因:这个报错有两层含义。一是postgis-3.dll本身没复制到lib目录;二是 DLL 在,但它依赖的 GEOS、PROJ、GDAL 等 DLL 不在bin目录,Windows 加载时找不到依赖链。
解决:先确认lib\postgis-3.dll存在,再确认bin目录下有geos.dll、proj.dll、gdal*.dll这类文件。bundle 的bin目录里通常有几十个 DLL,全部复制过去,不要只挑名字带 postgis 的。复制 DLL 前务必停服务,否则文件被占用会复制失败但你可能没注意。
4.3 报错 transform: couldn't project point
现象:CREATE EXTENSION成功了,但一执行ST_Transform就报投影相关错误,或者返回的坐标明显不对。
原因:PROJ 的数据文件(proj.db 等)没放对位置。PROJ 6 以后把投影参数从文本文件改成了 SQLite 数据库proj.db,如果这个文件不在 PROJ 能找到的路径下,投影转换就会失败。
解决:确认 bundle 的share目录下是否有proj子目录,把它整体复制到 PostgreSQL 的share目录下。有些 bundle 会把 proj 数据放在share\contrib或直接share下,按实际结构对应复制。复制后重启服务再测ST_Transform。
4.4 报错 permission denied 或文件被占用
现象:复制 DLL 时提示Access is denied或另一个程序正在使用此文件。
原因:PostgreSQL 服务还在运行,postgis-3.dll被 postgres 进程加载着,Windows 不允许覆盖正在使用的 DLL。
解决:先net stop postgresql-x64-12,确认服务真的停了(任务管理器里没有 postgres.exe 进程),再复制。如果停服务后还占用,检查是不是有 pgAdmin 或其他客户端连着,把它们也关掉。复制完再启动服务。
4.5 报错版本不匹配或 extension "postgis" has no update path
现象:CREATE EXTENSION postgis;提示找不到匹配版本,或者从旧版本升级时报没有升级路径。
原因:bundle 的版本和当前 PostgreSQL 大版本不匹配,比如拿 pg12 的包往 PG14 上装;或者数据库里已经装了旧版 PostGIS,想直接覆盖但缺少升级脚本。
解决:先SELECT version();确认 PG 大版本,再核对 bundle 文件名里的 pg 编号。如果是升级场景,不要直接覆盖,应该用ALTER EXTENSION postgis UPDATE;,并确保share/extension里有对应的升级 SQL(如postgis--3.3.0--3.4.2.sql)。跨大版本升级 PostgreSQL 时,PostGIS 也要跟着换对应 pg 版本的 bundle。
5. 让这套环境真正好用:批量部署脚本和版本升级的稳妥做法
装通一次之后,如果你要给团队多台机器部署,或者以后要升级 PostGIS 小版本,手动复制容易漏文件。我一般会写一个 PowerShell 脚本把复制逻辑固化下来,参数化 PostgreSQL 路径和 bundle 路径:
param( [string]$PgRoot = "C:\Program Files\PostgreSQL\12", [string]$Bundle = "D:\postgis-bundle", [string]$ServiceName = "postgresql-x64-12" ) # 停服务,避免 DLL 被占用 Stop-Service $ServiceName -Force # 按目录复制,-Recurse 保证子目录一起过去 Copy-Item "$Bundle\bin\*" "$PgRoot\bin\" -Recurse -Force Copy-Item "$Bundle\lib\*" "$PgRoot\lib\" -Recurse -Force Copy-Item "$Bundle\share\extension\*" "$PgRoot\share\extension\" -Recurse -Force # 如果 bundle 带 proj 数据,一并复制 if (Test-Path "$Bundle\share\proj") { Copy-Item "$Bundle\share\proj\*" "$PgRoot\share\proj\" -Recurse -Force } Start-Service $ServiceName Write-Host "PostGIS bundle 复制完成,服务已重启"这个脚本的关键点是Stop-Service -Force和-Recurse -Force。前者确保没有残留进程锁文件,后者保证子目录和只读文件也能覆盖。参数化之后,换 PG 版本或换机器只改三个变量。
升级 PostGIS 小版本时,稳妥顺序是:先备份数据库(pg_dump),停服务,用新 bundle 覆盖文件,启动服务,然后在每个已启用 PostGIS 的库里执行ALTER EXTENSION postgis UPDATE;和ALTER EXTENSION postgis_raster UPDATE;。不要跳过备份,因为扩展升级偶尔会改系统表结构,出问题回滚很麻烦。
验证升级是否成功,除了PostGIS_Full_Version(),还可以查扩展版本:
SELECT extname, extversion FROM pg_extension WHERE extname LIKE 'postgis%';这条会列出 postgis、postgis_raster 等所有相关扩展的当前版本,和 bundle 版本对得上就说明升级到位了。
最后说个我自己的习惯:每次装完 PostGIS,我都会把PostGIS_Full_Version()的输出存一份到项目文档里,标注清楚 PostgreSQL 版本、bundle 文件名、安装日期。因为过几个月再回来排查问题时,你很难记得当时装的是 3.4.2 还是 3.4.1,而版本差异往往就是玄学 bug 的根源。这套 bundle 方案在 Windows 上算是省心程度最高的做法,把依赖一次性打包的思路值得记住。希望帮到你。
本文还有配套的精品资源,点击获取