简介:PostGIS 3.5.0 安装包(适配 PostgreSQL 17、64位系统)为 GIS 开发者和数据库管理员提供了一站式空间数据扩展方案。它基于 PostgreSQL 增添空间对象类型、空间索引与地理分析函数,支持点线面等数据管理,适用于城市规划、交通物流、环境监测等场景。压缩包共1317个文件,包含大量 sql 脚本(建库建表与扩展安装)、dll 动态库、csv 示例数据以及 tif 栅格数据等,整体体积约130.69MB,可满足从基础安装到高级分析的需求。已有193人学习下载。资源内置 pgrouting、pointcloud、address_standardizer、postgis_tiger_geocoder 等扩展控制文件,并附有 bat 批处理、pl 函数及 json/geojson 等地理数据样例,便于用户快速完成配置并开展路径分析、点云处理和地理编码实验。
1. 一个 zip 包解决 Windows 上的空间数据库环境:postgis-bundle-pg17-3.5.0x64.zip 是什么
做 GIS、LBS 或者任何要和经纬度打交道的项目,Windows 上配 PostgreSQL + PostGIS 通常是个劝退过程:先装数据库,再装 PostGIS,版本不匹配就白忙;想卸载重来,注册表、服务、环境变量留下一堆痕迹。而标题里这个postgis-bundle-pg17-3.5.0x64.zip,是官方出的一种免安装分发形态:PostgreSQL 17 和 PostGIS 3.5.0 以及它们依赖的 GEOS、GDAL、PROJ 等底层库,全部打包在一个压缩包里,解压即用,不写注册表、不装系统服务、不改 PATH。它解决的是这样一类问题——本地快速起一个带空间能力的数据库跑业务验证,或者把同一个环境原样拷贝到离线内网机器上,又或者同一台机器同时跑多套不同版本的实例互不干扰。这篇文章直接讲怎么把这个压缩包变成一个真正能跑空间查询的数据库,以及那些只靠官方文档根本查不到的坑。
2. 解压先别急着启动:目录结构与版本搭配逻辑
拿到压缩包的第一件事不是双击解压,而是先搞清楚解压出来的是什么。这个包的目录结构和常规的 PostgreSQL 免安装版类似,但多了 PostGIS 这一层,每个目录承担的角色完全不同。很多人图快,直接运行里面自带的某个 bat 或 exe,结果数据目录、端口全被默认值绑死,后面改起来非常被动。我一般习惯先花两分钟把目录看一遍,再决定数据目录放在哪。
2.1 解压后的核心目录:bin、lib、share 各管什么
解压之后你会看到一个以postgis-bundle-pg17-3.5.0x64命名的文件夹,真正起作用的是下面这几个子目录:
bin:PostgreSQL 和 PostGIS 的可执行文件,包括initdb、pg_ctl、psql、createdb、pg_dump。后面所有命令都从这里进入。lib:PostGIS 运行时要加载的 DLL,包括 GEOS、GDAL、PROJ 这些底层库。这个目录是免安装的关键——PostGIS 的几何计算、坐标转换、栅格读写能力都在这些动态库里,bundle 把它们全部按匹配好的版本打包了。share/extension:PostGIS 的扩展控制文件,postgis.control、postgis--3.5.0.sql都在这里。PostgreSQL 执行CREATE EXTENSION postgis时,就是从这个目录读取安装脚本。data:压缩包里预先初始化好的一个数据库集群目录。注意,这个目录我建议不要直接用,后面第 3 章会说明为什么。pgAdmin 4相关文件:图形化管理工具,日常命令行够熟的话可以忽略。
理解这个结构之后,你就明白为什么这个包能被“原样拷贝”——它不依赖系统注册表,所有依赖项都在lib目录里,所有扩展脚本都在share目录里。把整个文件夹拷到一台没有安装过任何数据库的机器上,只要路径不变,就能直接跑起来。这也是它比安装版更适合离线交付的原因。
2.2 为什么这个包值得用:把 GEOS/GDAL/PROJ 的版本地狱打包了
PostGIS 不是 PostgreSQL 的一个简单插件,它底层依赖一大堆 C 库:GEOS 负责几何拓扑运算,GDAL 负责栅格与矢量格式转换,PROJ 负责坐标系投影变换,还有 libxml2 负责 GML 解析。这些库之间还有版本依赖关系——PostGIS 3.5.0 要求 GEOS 3.12 以上,PROJ 也有最低版本要求。在 Windows 上单独部署 PostGIS,意味着你要自己去下载并匹配这些库的 DLL 版本,稍有偏差就会出现“函数找不到”或者运行时崩溃。
而postgis-bundle-pg17-3.5.0x64.zip把这层关系全部处理好了。lib目录里打包的是和 PostGIS 3.5.0 一起编译验证过的依赖版本,不需要单独安装 GEOS、GDAL、PROJ。这个包用起来是一个整体,升级也是整体替换,不会出现某个 DLL 被系统里另一个软件的版本覆盖这种玄学问题。它的设计目标就是“免安装、免配置、免依赖地狱”。
和安装版相比,取舍在于:安装版会帮你注册 Windows 服务、配置 PATH、处理防火墙规则,适合一台机器只跑一个数据库的稳定场景;而 zip 包把决定权交给你——服务、端口、数据目录全部自己掌控,代价是这些步骤需要自己动手。对开发机、测试环境、多版本并存的要求来说,这个代价是值得的。
2.3 动手前先规划实例参数:端口、数据目录、字符集
解压之后不要直接跑,先把下面几个参数定下来。它们是你这个实例的“身份证”,后面所有命令都围绕它们展开。
| 参数 | 推荐值 | 原因 |
|---|---|---|
| 端口 | 5432(已被占用则用 5433) | 默认端口,但系统里装过其他 PostgreSQL 时容易冲突 |
| 数据目录 | D:\pgdata\pgis17 | 放在解压目录之外,方便备份和整体迁移 |
| 字符集 | UTF8 | 支持中文和全球字符,避免乱码 |
| 排序规则 | C | 避免 Windows 中文 locale 在 initdb 阶段的兼容性问题 |
| 超级用户 | postgres | 保持默认职责清晰,业务账号另行创建 |
| 认证方式 | scram-sha-256 | 密码加密传输,PostgreSQL 17 默认推荐 |
这里特别强调字符集和排序规则。Windows 中文系统的默认 locale 是Chinese (Simplified)_China.936,PostgreSQL 的initdb在 Windows 上对这类 locale 的支持并不理想,直接用默认值容易在初始化阶段报错。所以我会在命令里显式指定--locale=C -E UTF8,让数据库使用 C 排序规则配合 UTF8 编码。代价是中文文本的排序遵循字节序而不是拼音规则,但对绝大多数空间数据库场景来说,这个取舍可以接受,而且能避免一个很大的初始化失败风险。
3. 从解压到跑通第一个空间查询:初始化、启动、建扩展
前面把结构看明白了,参数也定了,后面就是纯操作。这一步的目标很明确:让SELECT ST_AsText(ST_GeomFromText(...))这条查询能正常返回结果。我会把完整的命令序列按顺序写出来,命令背后的参数含义也会逐个说明——这些参数不是背下来的,是遇到报错时排错要用的。
3.1 初始化数据库集群:initdb 与密码文件
先创建数据目录的父目录,然后用initdb初始化集群。我习惯把密码先写进一个临时文件,避免在命令行里直接暴露密码,也避免交互式输入在自动化脚本里卡住。
mkdir D:\pgdata cd /d D:\pgis\postgis-bundle-pg17-3.5.0x64\bin echo Strong_P@ssw0rd > D:\pgdata\pgis17_pw.txt initdb -D D:\pgdata\pgis17 ^ -E UTF8 ^ --locale=C ^ -U postgres ^ -A scram-sha-256 ^ --pwfile=D:\pgdata\pgis17_pw.txt del D:\pgdata\pgis17_pw.txt-D指定数据目录,这个目录必须不存在或者为空,initdb会创建它。-E UTF8设置数据库集群的默认编码。--locale=C设置排序规则,这两项在 Windows 中文系统上必须同时显式指定,否则可能直接报 locale 错误。-U postgres指定超级用户名。-A scram-sha-256设置默认的认证方式,PostgreSQL 17 里这是最安全的密码存储和传输方案。--pwfile从文件读取密码,文件内容就是一行密码,初始化完成后立刻删除。
初始化成功后会看到以Success. You can now start the database server结尾的提示。如果中途报错,最常见的就是 locale 问题,确认命令里的--locale=C -E UTF8都写上了再重试。
3.2 用 pg_ctl 启动与停止:日志文件与状态检查
initdb完成之后,数据库还没有运行。用pg_ctl启停实例,这是免安装版本管理进程的标准方式。
cd /d D:\pgis\postgis-bundle-pg17-3.5.0x64\bin pg_ctl -D D:\pgdata\pgis17 -l D:\pgdata\pgis17\server.log start pg_isready -p 5432 pg_ctl -D D:\pgdata\pgis17 status-l参数指定服务器日志的写入文件,这个文件很重要,后面所有服务端错误都会记录在这里,排查问题第一件事就是看它。pg_isready检查端口连通性,返回accepting connections表示数据库已经就绪。pg_ctl status显示进程状态。
停止时我会用-m fast而不是默认模式,区别在于fast会回滚所有活跃事务然后正常关闭,相当于让数据库“体面地退场”,不会留下需要恢复的中间状态。日常维护路径是:
pg_ctl -D D:\pgdata\pgis17 stop -m fast启动和停止命令里的数据目录路径,和初始化时保持一致,不要换路径,否则会报“数据目录不匹配”。
3.3 创建 PostGIS 扩展并验证版本
数据库起来之后,进入每个业务库安装 PostGIS 扩展。注意:PostGIS 扩展是按数据库安装的,不是在集群级别安装一次就全局生效。你需要在哪个库用空间功能,就在哪个库里执行CREATE EXTENSION。
psql -U postgres -d postgres -c "CREATE EXTENSION postgis;" psql -U postgres -d postgres -c "CREATE EXTENSION postgis_raster;" psql -U postgres -d postgres -c "SELECT PostGIS_Full_Version();"-d postgres指定要连接的数据库,-c直接执行单条 SQL。第一条创建 PostGIS 主扩展,包含几何类型、空间索引、空间函数;第二条是栅格扩展,处理卫星影像、DEM 这类数据,不需要栅格能力的话可以省略。第三条是验证命令,PostGIS_Full_Version()返回完整的版本信息,输出类似:
POSTGIS="3.5.0" [EXTENSION] PGSQL="170" GEOS="3.12.x" PROJ="9.x.x"重点看三处:POSTGIS字段是不是 3.5.0,PGSQL是不是 170,GEOS的版本号是不是 3.12 或更高。这三项匹配正确,说明扩展安装没有版本层面的隐患。
3.4 空间函数冒烟测试:一个点查询跑通全链路
扩展装好了,跑一条最简单的空间查询验证全链路——从函数调用、几何类型解析到坐标输出是否正常。
psql -U postgres -d postgres -c "SELECT ST_AsText(ST_GeomFromText('POINT(116.39 39.90)', 4326));"预期输出:
st_astext ----------- POINT(116.39 39.9)这行结果说明几件事:ST_GeomFromText能正确解析 WKT 格式的几何对象,ST_AsText能正确序列化输出,4326 坐标系被正常识别。如果这一步报,不用接着往下做了,先回头查第 5 章的问题排查。再顺手验证一下坐标系表是否完整:
psql -U postgres -d postgres -c "SELECT count(*) FROM spatial_ref_sys;"这张表由 PostGIS 扩展创建,包含全球常用坐标系定义,行数正常是几千条。如果查询结果是 0,说明扩展安装不完整,卸载重装扩展通常能解决。
4. 进阶:多实例并存与开机自启
跑通一条查询之后,这套免安装方案真正的优势才开始显现。同一套postgis-bundle-pg17-3.5.0x64.zip解压目录,可以同时管理多个完全隔离的数据库实例;也可以注册成 Windows 服务,让数据库在系统启动时自动拉起。这两个能力是安装版 PostgreSQL 不容易做到的,也是做多项目交付或者服务器部署时最常用的两个操作。
4.1 同一套包跑多个实例:端口和数据目录拆开
一个解压目录里的二进制文件是共享的,但“实例”由数据目录和端口共同定义。因此只要数据目录不同、端口不同,就能在同一套二进制上并行跑多个互不干扰的数据库,适合在开发机上同时维护多个项目的环境。
cd /d D:\pgis\postgis-bundle-pg17-3.5.0x64\bin echo Another_P@ssw0rd > D:\pgdata\pgis17_demo_pw.txt initdb -D D:\pgdata\pgis17_demo ^ -E UTF8 ^ --locale=C ^ -U postgres ^ -A scram-sha-256 ^ --pwfile=D:\pgdata\pgis17_demo_pw.txt pg_ctl -D D:\pgdata\pgis17_demo -o "-p 5433" -l D:\pgdata\pgis17_demo\server.log start del D:\pgdata\pgis17_demo_pw.txt关键在启动命令的-o "-p 5433":-o把参数直接传给 PostgreSQL 服务器进程,这里指定新实例监听 5433 端口。第一个实例保持 5432,第二个用 5433,互不冲突。访问时用-p指定端口:
psql -U postgres -d postgres -p 5433 -c "SELECT PostGIS_Full_Version();"要注意的是,每个实例的数据目录里都有自己的postgresql.conf和pg_hba.conf,端口号可以通过-o临时指定,也可以直接改配置文件。我一般建议把端口写进配置文件而不是每次用-o,避免启动时漏传参数导致端口冲突。
4.2 注册 Windows 服务:让数据库开机自启
开发机无所谓,但部署到服务器上,总不能让数据库挂了之后手动跑pg_ctl start。用pg_ctl register把实例注册成 Windows 服务,系统启动时自动拉起数据库进程。
cd /d D:\pgis\postgis-bundle-pg17-3.5.0x64\bin pg_ctl register ^ -N PostgreSQL-PGIS17 ^ -D D:\pgdata\pgis17 ^ -U NT AUTHORITY\NetworkService ^ -P "Strong_P@ssw0rd" ^ -o "-p 5432"-N指定服务名称,之后在 Windows 服务管理器里看到的就是这个名字。-U和-P指定服务登录账号和密码,默认用NT AUTHORITY\NetworkService是权限最小的选择,但也意味着该账号必须对数据目录有完全控制权限,否则服务起不来。
如果服务启动失败,先检查数据目录权限。给 NetworkService 账号授权数据目录的完全控制权限:
icacls D:\pgdata\pgis17 /grant "NT AUTHORITY\NetworkService:(OI)(CI)F"授权后重新启动服务。注销服务用pg_ctl unregister -N PostgreSQL-PGIS17。注册服务之后,日常启停就不再用pg_ctl start/stop了,而是通过 Windows 服务管理,否则服务管理器里的状态会与实际进程不一致,这是很多初次使用者容易踩的坑。
4.3 日常巡检:连接状态与数据库健康检查
多实例运行之后,需要定期检查每个实例是否健康。我最常用的三个命令都很短,适合写进维护脚本:
pg_isready -h localhost -p 5432 pg_isready -h localhost -p 5433 psql -U postgres -d postgres -p 5432 -c "SELECT pid, state, query FROM pg_stat_activity WHERE state = 'active';"pg_isready只报“连得上/连不上”,适合快速巡检;pg_stat_activity能看到当前活跃查询,排查长时间挂起的事务。做 GIS 项目时常见的一种情况是,某个空间查询扫描了大数据量的表,一直占着连接不释放,这条 SQL 能帮你第一时间定位到是哪个会话在跑。
5. 避坑:Windows 上 postgis-bundle 最容易翻车的 5 个现场
跑通一次不难,但换一台机器、换一个环境,各种“玄学”问题就会冒出来。下面这 5 个坑是我在多次部署里反复遇到的,每个都按“现象→原因→解决”写清楚,照着排查能省大量时间。
5.1 psql 连上了一个“别人的” PostgreSQL
现象:输入psql --version显示的是 15 甚至 14,根本不是 bundle 里的 17;或者psql -U postgres -d postgres连接时报密码错误,而这个密码明明是对的。
原因:系统 PATH 环境变量里已经存在其他 PostgreSQL 的bin目录,而那个目录里的psql被优先找到了。更隐蔽的情况是某些 GIS 软件自带 PostgreSQL 客户端,把自己的目录塞进了 PATH。
解决:查where psql看到底调用了哪个路径。命令行里统一用绝对路径进入 bundle 的 bin 目录,或者临时把 bundle 的 bin 置顶:
set PATH=D:\pgis\postgis-bundle-pg17-3.5.0x64\bin;%PATH%5.2 initdb 在中文系统上被打回票
现象:执行initdb时提示invalid locale name,或者直接报could not find locale "Chinese (Simplified)_China.936"之类的错误。
原因:Windows 中文系统的默认 locale 传递给 PostgreSQL 后,initdb 对这类组合的支持不完整,导致初始化失败。
解决:不要依赖系统默认值。初始化命令里显式带上--locale=C -E UTF8,这两个参数配对使用,C locale 配合 UTF8 编码是 Windows 上最稳妥的组合。之后在数据库里存取中文数据没有任何问题,只是排序规则按字节序处理。
5.3 CREATE EXTENSION 报扩展控制文件找不到
现象:执行CREATE EXTENSION postgis;报错,提示could not open extension control file "postgis.control",附带一句No such file or directory。
原因:PostgreSQL 在share/extension目录下找扩展定义文件,但 bundle 解压目录的路径没有被正确识别,或者解压后目录结构不完整。
解决:先确认share\extension\postgis.control文件存在。如果存在,检查解压路径里是否有中文、空格或特殊字符——PostgreSQL 在 Windows 上对这类路径的处理很容易出问题,把整个 bundle 目录移到纯英文路径下重新解压,问题基本消失。如果文件缺失,重新解压整个压缩包,不要只拷贝部分文件。
5.4 同一台机器上另一个数据库实例占用了 5432
现象:pg_ctl start启动成功,但pg_isready -p 5432显示连接的是另一个数据库,数据对不上;或者启动时直接报could not bind to address,端口被占用。
原因:机器上已经有其他 PostgreSQL 实例或软件占用了 5432。bundle 默认配置也监听 5432,两个实例撞车。
解决:初始化或启动时改端口。最干净的做法是在 2.3 节规划参数阶段就把端口定为 5433 或更高,然后所有命令里用-p指定。如果已经初始化了,可以改postgresql.conf里的port参数后重启,或者在pg_ctl start时加-o "-p 5433"临时覆盖。检查端口占用:
netstat -ano | findstr :5432看到 LISTENING 状态的 PID,再去任务管理器确认是哪个进程。
5.5 服务注册成功但启动失败:数据目录权限不对
现象:pg_ctl register成功,Windows 服务管理器里能看到服务,但点击启动后立即报错,事件日志里写着could not open data directory或权限拒绝。
原因:服务以NT AUTHORITY\NetworkService身份运行,该账号对数据目录没有读写权限。数据目录如果是手动创建的,默认权限只给当前用户。
解决:给服务账号授权数据目录的完全控制权限,用 4.2 节里的icacls命令,然后重试启动。如果还不成功,把服务账号换成当前登录用户,-U 当前用户名 -P 登录密码重新注册。问题解决后要养成一个习惯:数据目录和备份目录的权限配置,和注册服务这一步一起做,别等服务起不来再想起来。
6. 收尾:每次部署完,花三分钟做一次版本匹配自查
最后分享一个我每次部署完postgis-bundle-pg17-3.5.0x64.zip之后必做的验证动作——把PostGIS_Full_Version()的输出逐字段检查一遍。
psql -U postgres -d postgres -c "SELECT PostGIS_Full_Version();"输出类似:
POSTGIS="3.5.0" [EXTENSION] PGSQL="170" GEOS="3.12.x" PROJ="9.x.x" LIBXML="2.9.x"逐个字段说:POSTGIS是扩展自身版本,必须是 3.5.0;PGSQL是配套的 PostgreSQL 版本,对应 17;GEOS是底层几何库版本,PostGIS 3.5.0 要求 3.12 以上,低于这个版本会导致部分空间函数行为异常甚至崩溃;PROJ是坐标投影库,低于依赖版本会在执行ST_Transform时出问题。这串输出里的版本号,就是整个包最核心的“体检报告”。我见过有人把另一个项目里的lib目录拷过来覆盖,结果报错牌全打在 GEOS 版本不匹配上,查了半天。
配合这个自查,我还有一个冒烟测试习惯:跑一条点查询、查一次spatial_ref_sys行数、再执行一次CREATE EXTENSION验证。三分钟做完,这套环境才算真正交付。最后补一句关于备份的血泪经验:数据目录直接拷贝这种方式,在数据库运行状态下拷贝是危险的,数据文件处于不一致状态时,恢复出来可能直接起不来。我现在的习惯是停库后用文件备份,不停库则一律pg_dump:
pg_dump -U postgres -d 你的数据库名 -Fc -f 备份文件名.dump这个格式是自定义压缩格式,恢复灵活,也支持选择性恢复表。恢复前先建好带 PostGIS 扩展的数据库,再执行pg_restore -U postgres -d 新库名 备份文件名.dump,基本不会翻车。用免安装包最大的优势本来就是环境可复制、可迁移,配合干净的备份习惯,这套方案才能在各种项目里反复用。希望这次的完整拆解,能帮你把postgis-bundle-pg17-3.5.0x64.zip真正变成顺手的环境工具。
本文还有配套的精品资源,点击获取