恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
PostgreSQL 12 Windows 下 PostGIS 3.4.2 离线部署与避坑指南
首页
资讯中心
/
PostgreSQL 12 Windows 下 PostGIS 3.4.2 离线部署与避坑指南
PostgreSQL 12 Windows 下 PostGIS 3.4.2 离线部署与避坑指南
发布时间:2026/10/11 6:42:14
简介这是PostGIS 3.4.2在PostgreSQL 1264位环境下的安装包面向需要快速搭建空间数据库的GIS开发者、数据分析师及PostgreSQL管理员。压缩包整合了扩展核心组件、SQL脚本、控制文件与运行库共1281个文件包含895个SQL脚本、78个DLL动态库、74个CSV数据文件以及GeoTIFF、字体配置、工具程序等整体约129.44MB便于离线安装与分发。已有112人学习适合在生产或开发环境中部署空间数据处理能力。使用后可获得完整的PostGIS扩展模块涵盖几何处理、地理坐标系转换、空间索引及栅格数据支持并附带常用数据格式读写工具链有效避免逐个依赖配置的繁琐过程。1. postgis-bundle-pg12-3.4.2x64.zip 是什么为什么一个 zip 能解决 PostgreSQL 12 的 PostGIS 安装问题你在 Windows 上装好了 PostgreSQL 12 x64正打算把手里的 GIS 数据倒进去却发现官方安装途径要么连不上镜像要么在 Stack Builder 里找不到与 PG 12 匹配的组件屏幕停在下载界面不动。这时候有人丢来一个文件postgis-bundle-pg12-3.4.2x64.zip。这个 zip 是 PostGIS 3.4.2 针对 PostgreSQL 12、64 位 Windows 系统的预编译二进制包里面是扩展控制文件、建扩展用的 SQL 脚本、核心动态库postgis-3、GEOS、GDAL、PROJ以及 shp2pgsql、raster2pgsql 这类命令行工具。它的价值在于不依赖联网安装器适合内网服务器、离线环境以及 Stack Builder 反复安装失败时绕道手工部署。适合的人是已经在管 PG 安装目录、能接受手动复制文件、遇到问题愿意看日志的维护者。2. 安装前核对三个硬指标PG 位数、VC 运行库、服务权限2.1 核对 PostgreSQL 12.x 的 x64 与 pg_config 路径这个 zip 的文件名里有三个硬约束pg12指 PostgreSQL 12 大版本x64指 64 位3.4.2指 PostGIS 版本。三者任一不对后面都会以各种奇怪方式失败。最常见的错法是拿它去配 32 位的 PG 12或者配 PG 13/14——DLL 的文件名能对上但位数或符号集不一致Windows 直接报“无法加载”。我在装之前会先跑一条 SQLSELECT version(), current_setting(server_version_num);看version()返回里有没有64-bit字样以及版本号是不是 12.x 的正式版。命令行侧再用pg_config确认实际安装目录pg_config --bindir pg_config --pkglibdir pg_config --sharedir--pkglibdir对应 DLL 的目标目录--sharedir下面的extension子目录对应控制文件和 SQL 脚本的落点。很多人在这一步省事结果把扩展脚本复制到了share/postgresql/extension与 PG 实际查找的share/extension错位后面CREATE EXTENSION直接报 “could not open extension control file”。提示PG 12 的小版本12.0 到 12.22一般不影响 PostGIS 3.4.2 的二进制兼容性但 Beta/RC 版不要用扩展脚本里引用系统目录的方式在正式版里才有保证。2.2 先补装 Visual C 2015-2022 Redistributable (x64)顺带确认 VC 2013 运行时PostGIS 的 Windows 预编译包是用 Visual Studio 2015-2022 工具链做的运行时依赖 VC 库。搜索里高频出现的 “microsoft visual c 2015-2022 redistributable (x64) 下载” 和 “postgis 安装失败”在真实环境里高度相关装好 PG、复制好 DLL一执行CREATE EXTENSION就报 “无法加载库 postgis-3.dll”查下来多半是系统里根本没有 VC 2015-2022 x64 运行库。我一般会建议装两个东西Microsoft Visual C 2015-2022 Redistributable (x64)这是主依赖几乎覆盖 PostGIS 本体和 GEOS/GDAL 全部 DLL。Microsoft Visual C 2013 Redistributable (x64)某些老版本 GDAL 或第三方扩展会带 2013 的 CRT 依赖缺了它会在调用栅格功能时莫名崩溃。检查是否已装用命令行比在“程序和功能”里翻快reg query HKLM\SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64 /v Installed reg query HKLM\SOFTWARE\Microsoft\VisualStudio\12.0\VC\Runtimes\x64 /v Installed两条命令返回的Installed都应为0x1。如果缺失下载对应vc_redist.x64.exe并静默安装start /wait vc_redist.x64.exe /install /quiet /norestartVC 运行库装失败时Windows Installer 日志里经常出现“警告由于错误 1603”。1603 的本质是安装器无法完成注册或写文件原因多是权限不足或杀毒拦截。遇到它不要反复点安装改为“以管理员身份运行 临时退出实时防护”或者先卸载再装。2.3 确认服务账号对 lib 与 share 目录有读权限第三个核对项常被忽略PostgreSQL 在 Windows 上以服务方式运行服务账号如果不是本地管理员手动复制进去的 DLL 和 SQL 可能没有可读权限。现象是CREATE EXTENSION报权限错误或服务日志里出现could not access file postgis-3.dll: Permission denied。核对服务账号与安装目录sc qc postgresql-x64-12输出里SERVICE_START_NAME一般是NT AUTHORITY\NetworkService或自定义的postgres用户。再看C:\Program Files\PostgreSQL\12\lib和share\extension的安全属性确认该账号有“读取和执行”权限。如果之前是用管理员把文件复制进去的系统默认继承的权限通常没问题但如果你解压后手动移动过目录或者把 bundle 放在带特殊权限的磁盘上就容易翻车。补救命令icacls C:\Program Files\PostgreSQL\12\lib\postgis-3.dll /grant NT AUTHORITY\NetworkService:RX把NetworkService换成你环境里的实际账号。这一步做完再重启服务能挡掉不少“看着像 DLL 缺失、其实是权限不足”的假故障。3. 把 bundle 部署到 PG12 的 lib 与 share 目录复制命令和 postgresql.conf 改动3.1 先解压到独立目录避免路径过长与 DLL 混用拿到 zip 后第一件事不是直接解压到 PG 安装目录而是先解压到一个干净的工作目录比如C:\temp\pgis_bundle。这个 zip 内部一般是标准的 PostGIS Windows bundle 布局包内目录典型内容对应 PG 目标libpostgis-3.dll、geos_c.dll、proj DLL、gdal DLL%PGROOT%\12\libshare/extensionpostgis.control、postgis--3.4.2.sql、postgis_topology...%PGROOT%\12\share\extensionbinshp2pgsql、raster2pgsql、pgsql2shp 等命令行工具%PGROOT%\12\bindoc或README版本说明、许可文件可选不用复制先解压到独立目录再复制而不是直接在资源管理器里跨 zip 拖文件原因有两个一是 Windows 的路径长度限制在解压深层目录时容易踩坑比如share/extension下的长 SQL 脚本名二是 bundle 里的 DLL 之间有互相依赖中途复制一半就断开容易造成 DLL 版本混用后面排查起来无从下手。3.2 复制 DLL、控制文件与命令行工具PowerShell 与 xcopy 两种写法确认目录无误后我用 PowerShell 分三条命令复制并在复制前清掉旧版本的 postgis 文件避免新旧 DLL 混在一起$pgRoot C:\Program Files\PostgreSQL\12 $src C:\temp\pgis_bundle # 清除旧版 PostGIS 动态库与控制文件避免版本混用 Remove-Item $pgRoot\lib\postgis*.dll -ErrorAction SilentlyContinue Remove-Item $pgRoot\share\extension\postgis*.control -ErrorAction SilentlyContinue Remove-Item $pgRoot\share\extension\postgis*.sql -ErrorAction SilentlyContinue # 复制依赖库与扩展主体 Copy-Item $src\lib\*.dll $pgRoot\lib -Force Copy-Item $src\bin\*.exe $pgRoot\bin -Force -ErrorAction SilentlyContinue Copy-Item $src\share\extension\* $pgRoot\share\extension -Force -Recurse这段脚本有几处值得说Remove-Item只清postgis*不会动其他扩展的 DLL三个扩展名postgis、postgis_topology、postgis_raster都会生成自己的.control和--版本.sql文件所以用通配符一次清干净。复制bin目录时加-ErrorAction SilentlyContinue是因为不是所有 bundle 都带pgsql2shp缺一个命令文件不影响扩展可用性。如果你更习惯 cmd等价写法xcopy /y /s C:\temp\pgis_bundle\lib\*.dll C:\Program Files\PostgreSQL\12\lib\ xcopy /y /s C:\temp\pgis_bundle\share\extension\* C:\Program Files\PostgreSQL\12\share\extension\注意复制前务必确认 PostgreSQL 12 的 Windows 服务处于停止状态否则 DLL 被占用复制不进去或者复制一半被替换导致进程里混着两个版本。常见做法是先停服务再复制或者复制完立即重启服务。3.3 修改 postgresql.confshared_preload_libraries 与 PROJ_LIB复制完文件后需要编辑%PGDATA%\postgresql.conf。关键配置有两个# 预加载 PostGIS 动态库。注意文件名是 postgis-3不是 postgis shared_preload_libraries postgis-3 # 如果用到栅格功能建议显式启用 GDAL 驱动 # postgis.gdal_enabled_drivers GTiff PNG JPEGshared_preload_libraries不是 PostGIS 能跑起来的硬性要求——只用几何类型和函数的话CREATE EXTENSION postgis会在会话里按需加载。但如果你要用postgis_topology和postgis_raster或者希望postgis_full_version()一次看到 GEOS/GDAL/PROJ 的版本预加载能避免会话与后台进程加载不一致。文件名写postgis-3是postgis.control里module_pathname指定的别写成本体文件名postgis-3.dll或旧版的postgis-2。GDAL 数据路径是另一个常见坑bundle 里如果带proj.dbPG 的 Windows 服务进程未必能找到。在 GDAL 3.x 里PROJ_LIB环境变量决定坐标转换数据的查找目录设置方式[System.Environment]::SetEnvironmentVariable(PROJ_LIB, C:\temp\pgis_bundle\share\proj, Machine)把路径指向包内proj.db所在目录。设置成系统级环境变量后服务重启时会继承不会出现“CREATE EXTENSION 成功但 ST_Transform 报 cannot open proj.db”的问题。3.4 重启服务并验证 DLL 加载修改完后重启服务。用管理员 PowerShell 执行net stop postgresql-x64-12 net start postgresql-x64-12服务名不一定统一用sc query | findstr postgres先确认。重启后先看日志Windows 下 PG 日志一般在%PGDATA%\log关键报错有两类could not load library C:/Program Files/PostgreSQL/12/lib/postgis-3.dll——说明 VC 运行库缺失或 DLL 依赖不全回到 2.2。服务一直重启——多半是shared_preload_libraries写错文件名先注释掉再重启。验证服务在听端口pg_isready -h 127.0.0.1 -p 5432返回accepting connections就说明服务侧没问题接下来进数据库建扩展。4. 让扩展真正生效CREATE EXTENSION 与空间函数自检4.1 用 postgis_version() 验证扩展与依赖库完整复制文件和改配置只是“安装”真正让 PostGIS 生效的是CREATE EXTENSION。这一步会执行postgis--3.4.2.sql里的全部对象定义创建spatial_ref_sys、geometry类型、ST_函数族以及操作符。CREATE EXTENSION postgis; SELECT postgis_version(); SELECT postgis_full_version();postgis_version()返回类似3.4.2postgis_full_version()输出更完整会列出编译时使用的 GEOS、GDAL、PROJ、libxml 版本。如果postgis_full_version()里出现GEOS 3.x之类说明依赖库加载正常。这一步有两个典型的失败模式报ERROR: could not open extension control file C:/.../share/extension/postgis.control回到 3.2检查控制文件是否真的复制到了 PG 的share\extension而不是系统里另一份 PG 安装目录。报ERROR: could not load library postgis-3.dll回到 2.2补 VC 运行库再用dumpbin /dependents postgis-3.dll查看缺失的依赖项。如果这个数据库是从旧环境restore出来的并且已经存在 postgis 扩展就不要重复CREATE EXTENSION直接看第 5 章的升级路径。4.2 建一个 geometry 表并跑通 ST_MakePoint 与 ST_Transform扩展建好后先不急着导入大表。我一般会用一个小表自检几何类型和坐标系转换是否正常CREATE TABLE public.poi_test ( id bigserial PRIMARY KEY, name text NOT NULL, geom geometry(Point, 4326) NOT NULL ); INSERT INTO public.poi_test (name, geom) VALUES (北京, ST_SetSRID(ST_MakePoint(116.4074, 39.9042), 4326)), (上海, ST_SetSRID(ST_MakePoint(121.4737, 31.2304), 4326)); SELECT name, ST_AsText(geom) AS wkt, ST_X(geom) AS lon, ST_Y(geom) AS lat FROM public.poi_test;说明一下参数geometry(Point, 4326)声明字段类型是二维点、SRID 为 4326WGS84 经纬度。ST_MakePoint生成不带 SRID 的几何必须用ST_SetSRID把坐标系信息标上去否则后续的空间索引和ST_Transform都会因为 SRID0 而按“未知坐标系”处理。ST_AsText用于肉眼查验ST_X/ST_Y取坐标值。如果业务坐标是 GCJ-02 或 CGCS2000不要直接改 SRID 骗自己而是用ST_Transform(geom, 目标SRID)做真实转换。CGCS2000 的 EPSG 是 4490WGS84 是 4326两者椭球接近但不等同混用会在跨带投影时出现厘米级偏差。4.3 postgis、postgis_topology、postgis_raster三种扩展的分工PostGIS 3.4 把功能拆成了多个扩展。很多人只建了postgis到用时才发现没有raster类型这不是安装失败而是没建对扩展。扩展名提供能力何时需要postgis几何类型、空间索引、ST_ 函数、spatial_ref_sys基础必装postgis_topology拓扑关系处理、TopoGeometry做地籍、网络分析时postgis_raster栅格类型、栅格代数运算遥感影像、DEM 分析时CREATE EXTENSION postgis_topology; CREATE EXTENSION postgis_raster;postgis_topology和postgis_raster在 PG 12 上建议先预加载postgis-3否则可能出现type topology does not exist之类的前后顺序错误。建这三个扩展的先后顺序没有严格要求但一定先建postgis。postgis_raster建完还会多出raster_columns和raster_overviews两张目录表用来管理栅格数据的元数据。5. 避坑postgis 安装失败最常见的 5 个真实案例5.1 现象安装报告“警告由于错误 1603” → 原因安装器被权限或残留状态卡住 → 解决管理员重装或绕开 MSIWindows 上跑 PostGIS 图形安装器或 VC 安装器时弹窗提示 1603安装直接回滚。常见原因是安装器在写C:\Windows\Installer或注册表时被权限策略或杀毒实时防护拦下另一种是之前卸载不干净残留的安装状态让新安装无法覆盖。解决思路是先以管理员身份运行安装器若仍报 1603用vc_redist.x64.exe /repair修复现有 VC 运行时如果修复失败卸载 VC 2015-2022 后重启再重新安装。zip 这个包本身不需要 MSI所以我的实际做法是绕过图形安装器直接手动解压复制反而绕开了 1603。5.2 现象CREATE EXTENSION 报错无法加载 postgis-3.dll → 原因依赖 DLL 缺失或 VC 未装 → 解决补文件、补运行库执行CREATE EXTENSION postgis时提示could not load library postgis-3.dll。真正原因分两类一是lib目录里缺少postgis-3.dll或其依赖的geos_c.dll、gdal 相关 DLL二是 VC 运行库没装全。排查时先确认文件存在dir C:\Program Files\PostgreSQL\12\lib\postgis-3.dll存在就查依赖项。我习惯用 Dependencies 工具拖入postgis-3.dll看缺失的红色条目没有工具时用where /r C: geos_c.dll但不如 GUI 直观。解决补全缺失 DLL 或按 2.2 装 VC 2015-2022 x64重启 PG 服务后再试。5.3 现象提示 could not open extension control file → 原因复制错目录或多 PG 共存 → 解决按 pg_config --sharedir 对齐CREATE EXTENSION报找不到postgis.control但文件明明复制过。这种多半是复制进错了目录。PG 找扩展控制文件的位置由pg_config --sharedir决定默认是C:\Program Files\PostgreSQL\12\share\extension不是share\postgresql\extension也不是share\contrib。还有种隐蔽情况机器上装了多套 PG比如 9.6 和 12 共存当前psql连的实例是 12但你把文件复制到了另一套的目录。排查顺序先pg_config --sharedir再确认psql连的端口对应哪套实例最后把postgis.control和所有postgis*.sql放到正确目录。注意postgis.control里有一行module_pathname $libdir/postgis-3如果这行被改成绝对路径或旧文件名也会以同样错误出现。5.4 现象ST_Transform 报 PROJ 错误或打不开 proj.db → 原因服务进程没有 PROJ_LIB → 解决设系统环境变量并重启服务扩展建成功了几何也能插入但一执行ST_Transform就报PROJ: proj_assign_identifier或Cannot open proj.db。原因是 PG 的 Windows 服务进程在启动时没有拿到PROJ_LIB环境变量。注意在“系统属性 - 环境变量”里设置后如果不重启 PG 服务进程仍然沿用旧环境而且服务由 services.exe 拉起的不会继承手动打开的 PowerShell 里的用户变量。解决把PROJ_LIB设为系统级环境变量指向包内proj.db所在目录然后net stopnet start重启服务。如果 bundle 里找不到proj.db也可以单独下载 PROJ 数据包放一个目录再指向它但要保证proj.db版本和 bundle 里projDLL 的主版本匹配混用跨大版本的proj.db会以“数据库版本不兼容”报错。5.5 现象老库升到 3.4.2 后几何字段异常 → 原因只换 DLL 没走扩展升级 → 解决ALTER EXTENSION UPDATE 或 dump/restore从 2.x/3.x 老版本升级时直接替换 DLL 后老库里的geometry类型能建不能查报invalid byte sequence或type geometry already exists之类的问题。原因是没有走扩展升级路径PostGIS 的大版本升级不止是换 DLL还涉及数据结构变更比如 3.0 移除_ST_*函数、旧raster目录表迁移。正确做法是ALTER EXTENSION postgis UPDATE TO 3.4.2;如果老版本跨度太大或者升级脚本直接失败就别硬升。常见做法是pg_dump导出用--formatcustom新建一个库按 4.1 装上干净的 3.4.2再pg_restore导入。空间数据量大时导入后用CLUSTER或REINDEX重建空间索引会比一次性ALTER EXTENSION可控得多。6. 部署成一个脚本内网批量装 PostGIS 3.4.2 的实践技巧6.1 用 PowerShell 固化安装流程二次部署只跑一条命令如果要在内网多台 Windows 服务器上重复部署我不会每次手动复制文件而是把前面的步骤压缩成一个 PowerShell 脚本放进内网文件服务器新机器拉下来直接跑。脚本大致长这样param([string]$PgRoot C:\Program Files\PostgreSQL\12) $ErrorActionPreference Stop $ver $PgRoot\bin\pg_config.exe --version if ($ver -notmatch PostgreSQL 12) { throw bundle 只适配 PG 12 } # 1) 检查 VC 运行库 $vc14 Get-ItemProperty HKLM:\SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64 -ErrorAction SilentlyContinue if (-not $vc14 -or $vc14.Installed -ne 1) { throw 先装 VC 2015-2022 x64 } # 2) 复制 bundle 内容 Copy-Item $PSScriptRoot\lib\*.dll $PgRoot\lib -Force Copy-Item $PSScriptRoot\share\extension\* $PgRoot\share\extension -Force -Recurse # 3) 设置 PROJ_LIB 并重启服务 [System.Environment]::SetEnvironmentVariable(PROJ_LIB, $PSScriptRoot\share\proj, Machine) Restart-Service postgresql-x64-12 # 4) 创建数据库与扩展 $PgRoot\bin\psql.exe -U postgres -c CREATE DATABASE gis_db; $PgRoot\bin\psql.exe -U postgres -d gis_db -c CREATE EXTENSION postgis;这个脚本的设计要点是把 bundle 和脚本放在同一个目录直接用$PSScriptRoot推导路径避免每台机器手改绝对路径PgRoot作为参数遇到 PG 装在非默认盘符的机器直接覆盖$ErrorActionPreferenceStop保证某一步失败立即停止不会带着残缺环境继续。部署完我会顺手检查postgis_full_version()并跑一次 4.2 的小表自检确认覆盖。批量验证一条命令 $PgRoot\bin\psql.exe -d gis_db -tAc select postgis_full_version(); | Select-String 3.4.2我的习惯是把这个脚本连同安装日志落在内网交接文档里注明“bundle 解压目录不要用中文路径、服务账号需要读取权限”两行重点免得三个月后同事自己装又视而不见。这个方向说到底就是把“一次正确的手工安装”固化成资产收益比反复点安装器高得多希望帮到你。本文还有配套的精品资源点击获取