文章目录
-
- [一、PostGIS 简介](#一、PostGIS 简介)
-
- [1.1 什么是 PostGIS?](#1.1 什么是 PostGIS?)
- [1.2 PostGIS 能做什么?](#1.2 PostGIS 能做什么?)
- [二、安装与启用 PostGIS](#二、安装与启用 PostGIS)
-
- [2.1 安装方式(以 Ubuntu 为例)](#2.1 安装方式(以 Ubuntu 为例))
- [2.2 验证安装](#2.2 验证安装)
- 三、核心数据类型
-
- [3.1 geometry(几何类型)](#3.1 geometry(几何类型))
- [3.2 geography(地理类型)](#3.2 geography(地理类型))
- [3.3 常见几何子类型(OGC 标准)](#3.3 常见几何子类型(OGC 标准))
- 四、空间数据表示与输入
-
- [4.1 WKT(Well-Known Text)](#4.1 WKT(Well-Known Text))
- [4.2 WKB(Well-Known Binary)](#4.2 WKB(Well-Known Binary))
- [4.3 EWKT / EWKB(Extended WKT/Binary)](#4.3 EWKT / EWKB(Extended WKT/Binary))
- [4.4 GeoJSON](#4.4 GeoJSON)
- [4.5 常用构造函数](#4.5 常用构造函数)
- [五、空间参考系统(SRS)与 SRID](#五、空间参考系统(SRS)与 SRID)
-
- [5.1 什么是 SRID?](#5.1 什么是 SRID?)
- [5.2 设置与转换 SRID](#5.2 设置与转换 SRID)
- 六、空间关系与操作函数
-
- [6.1 空间谓词(返回布尔值)](#6.1 空间谓词(返回布尔值))
- [6.2 度量函数](#6.2 度量函数)
- [6.3 几何构造与编辑](#6.3 几何构造与编辑)
- 七、空间索引与性能优化
-
- [7.1 GiST 索引](#7.1 GiST 索引)
- [7.2 查询优化技巧](#7.2 查询优化技巧)
- 八、典型应用场景
-
- [8.1 POI(兴趣点)附近搜索](#8.1 POI(兴趣点)附近搜索)
- [8.2 行政区划包含判断](#8.2 行政区划包含判断)
- [8.3 路径规划(需结合 pgRouting)](#8.3 路径规划(需结合 pgRouting))
- [8.4 热力图/密度分析](#8.4 热力图/密度分析)
- [九、栅格数据支持(PostGIS Raster)](#九、栅格数据支持(PostGIS Raster))
- 十、与其他工具集成
- 十一、常见问题
-
- [11.1 坐标系混乱](#11.1 坐标系混乱)
- [11.2 性能瓶颈](#11.2 性能瓶颈)
- [11.3 数据质量](#11.3 数据质量)
PostgreSQL 与 PostGIS 结合,构成了一个功能强大、开源且符合标准的地理空间数据库系统。PostGIS 是 PostgreSQL 的一个扩展,用于存储、查询和分析地理信息(地理空间)数据。以下是对 PostGIS 地理信息数据处理的万字详解,涵盖核心概念、安装配置、数据类型、函数使用、索引优化、典型应用场景及性能调优等内容。
一、PostGIS 简介
1.1 什么是 PostGIS?
PostGIS 是一个遵循 Open Geospatial Consortium(OGC)标准的空间数据库扩展,为 PostgreSQL 提供了对地理空间数据的支持。它支持二维、三维甚至四维(含时间维度)的几何(Geometry)和地理(Geography)对象,并提供丰富的空间操作函数。
- 官网:https://postgis.net/
- 开源协议:GPLv2+
- 依赖库:GEOS(几何操作)、PROJ(坐标转换)、GDAL(栅格支持)、LibXML2(GML 支持)等
1.2 PostGIS 能做什么?
- 存储点、线、面、多边形、多点等几何对象
- 执行空间关系判断(如相交、包含、邻近)
- 计算距离、面积、长度等度量
- 坐标系转换(WGS84、UTM、Web Mercator 等)
- 支持地理坐标(球面)与投影坐标(平面)两种模型
- 支持栅格数据(自 PostGIS 2.0 起)
- 与 GIS 软件(如 QGIS、ArcGIS)无缝集成
二、安装与启用 PostGIS
2.1 安装方式(以 Ubuntu 为例)
bash
# 安装 PostgreSQL 和 PostGIS
sudo apt update
sudo apt install postgresql postgresql-contrib postgis
# 启用 PostGIS 扩展(在目标数据库中执行)
CREATE EXTENSION postgis;
CREATE EXTENSION postgis_topology; -- 可选,用于拓扑支持
CREATE EXTENSION fuzzystrmatch; -- 可选,用于地址匹配
CREATE EXTENSION postgis_raster; -- 若需栅格支持(PostGIS ≥ 3.0 需单独安装)
注意:不同操作系统和 PostgreSQL 版本安装方式略有差异。建议使用官方仓库或 Docker 镜像确保版本兼容。
2.2 验证安装
sql
SELECT PostGIS_Version();
-- 返回类似:3.4 USE_GEOS=1 USE_PROJ=1 USE_STATS=1
三、核心数据类型
PostGIS 引入了两种主要的空间数据类型:
3.1 geometry(几何类型)
- 基于笛卡尔坐标系(平面)
- 适用于局部区域(如城市、省域)的投影坐标系(如 EPSG:3857、EPSG:2381)
- 计算速度快,但不考虑地球曲率
3.2 geography(地理类型)
- 基于 WGS84 椭球体(经纬度,单位为度)
- 适用于全球范围计算(如飞行距离、跨洲分析)
- 使用球面几何计算,精度高但性能略低
建议:小范围用
geometry,大范围或需高精度距离/面积用geography。
3.3 常见几何子类型(OGC 标准)
| 类型 | 描述 |
|---|---|
| POINT | 单个点 (x, y) |
| LINESTRING | 折线,由多个点组成 |
| POLYGON | 封闭多边形,可含内环(洞) |
| MULTIPOINT | 多个点集合 |
| MULTILINESTRING | 多条线集合 |
| MULTIPOLYGON | 多个多边形集合 |
| GEOMETRYCOLLECTION | 混合几何类型集合 |
四、空间数据表示与输入
4.1 WKT(Well-Known Text)
人类可读的文本格式:
sql
'POINT(116.4 39.9)'::geometry
'POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))'::geometry
4.2 WKB(Well-Known Binary)
二进制格式,适合程序间传输。
4.3 EWKT / EWKB(Extended WKT/Binary)
PostGIS 扩展格式,支持 SRID:
sql
'SRID=4326;POINT(116.4 39.9)'::geometry
4.4 GeoJSON
可通过 ST_GeomFromGeoJSON() 导入:
sql
SELECT ST_GeomFromGeoJSON('{"type":"Point","coordinates":[116.4,39.9]}');
4.5 常用构造函数
ST_GeomFromText(wkt, srid)ST_Point(x, y)ST_MakePoint(x, y)ST_MakeLine(geom1, geom2)ST_MakePolygon(linear_ring)
五、空间参考系统(SRS)与 SRID
5.1 什么是 SRID?
Spatial Reference System Identifier,空间参考系统标识符。例如:
4326:WGS84(经纬度)3857:Web Mercator(Google Maps 使用)2381:北京54高斯-克吕格投影(中国常用)
5.2 设置与转换 SRID
sql
-- 创建带 SRID 的几何
SELECT ST_SetSRID(ST_Point(116.4, 39.9), 4326);
-- 坐标系转换
SELECT ST_Transform(geom, 3857) FROM my_table;
注意:
geometry类型的 SRID 不会自动参与计算,必须显式转换;geography默认为 4326。
六、空间关系与操作函数
6.1 空间谓词(返回布尔值)
| 函数 | 含义 |
|---|---|
ST_Equals(A, B) |
几何是否完全相同 |
ST_Intersects(A, B) |
是否相交 |
ST_Contains(A, B) |
A 是否完全包含 B |
ST_Within(B, A) |
B 是否在 A 内部(等价于 Contains) |
ST_Touches(A, B) |
边界接触但内部不相交 |
ST_Crosses(A, B) |
几何交叉(如线穿过面) |
ST_Disjoint(A, B) |
完全不相交 |
这些函数默认使用 DE-9IM 模型判断空间关系。
6.2 度量函数
| 函数 | 说明 |
|---|---|
ST_Distance(A, B) |
平面距离(geometry)或球面距离(geography,单位米) |
ST_Length(geom) |
线长度 |
ST_Area(geom) |
面积 |
ST_Perimeter(geom) |
多边形周长 |
示例(地理距离):
sql
SELECT ST_Distance(
'SRID=4326;POINT(116.4 39.9)'::geography,
'SRID=4326;POINT(121.5 31.2)'::geography
) AS distance_meters;
-- 返回上海到北京的球面距离(约 1067 km)
6.3 几何构造与编辑
| 函数 | 说明 |
|---|---|
ST_Buffer(geom, radius) |
生成缓冲区 |
ST_Union(geom1, geom2) |
合并几何 |
ST_Intersection(A, B) |
求交集 |
ST_Difference(A, B) |
A 减去 B |
ST_SymDifference(A, B) |
对称差集 |
ST_Centroid(geom) |
几何中心点 |
ST_ConvexHull(geom) |
凸包 |
七、空间索引与性能优化
7.1 GiST 索引
PostGIS 使用 GiST(Generalized Search Tree) 索引加速空间查询。
sql
-- 为 geometry 列创建空间索引
CREATE INDEX idx_mytable_geom ON my_table USING GIST (geom);
注意:仅当查询使用
&&(边界框相交)或空间谓词时,索引才生效。
7.2 查询优化技巧
- 使用
EXPLAIN ANALYZE分析执行计划 - 避免在索引列上使用函数(如
ST_Transform(geom, ...)),可预先转换存储 - 对大表进行分区(按区域或时间)
- 使用
ST_DWithin替代ST_Distance < x(可利用索引)
sql
-- 推荐写法(可走索引)
SELECT * FROM pois
WHERE ST_DWithin(geom, ST_Point(116.4,39.9)::geography, 1000); -- 1km 内
-- 不推荐(无法使用索引)
SELECT * FROM pois
WHERE ST_Distance(geom, ST_Point(116.4,39.9)::geography) < 1000;
八、典型应用场景
8.1 POI(兴趣点)附近搜索
sql
SELECT name, ST_Distance(geom, ref_point) AS dist
FROM pois, (SELECT 'SRID=4326;POINT(116.4 39.9)'::geography AS ref_point) t
WHERE ST_DWithin(geom, ref_point, 5000)
ORDER BY dist;
8.2 行政区划包含判断
sql
SELECT city.name
FROM cities, user_locations
WHERE ST_Contains(cities.boundary, user_locations.geom);
8.3 路径规划(需结合 pgRouting)
PostGIS 本身不提供路径算法,但可与 pgRouting 扩展结合实现最短路径、服务区分析等。
8.4 热力图/密度分析
使用 ST_SnapToGrid + GROUP BY 聚合点密度:
sql
SELECT ST_SnapToGrid(geom, 0.01, 0.01) AS grid, COUNT(*) AS cnt
FROM events
GROUP BY grid;
九、栅格数据支持(PostGIS Raster)
PostGIS 自 2.0 起支持栅格(如卫星影像、DEM 高程数据):
- 使用
raster类型 - 支持波段、像素值、重采样、裁剪等操作
- 可与矢量数据叠加分析(如提取某区域高程)
注意:PostGIS 3.0+ 将 raster 功能拆分为独立扩展
postgis_raster。
十、与其他工具集成
| 工具 | 集成方式 |
|---|---|
| QGIS | 直接连接 PostgreSQL/PostGIS 数据库 |
| GDAL/OGR | 使用 PG: 驱动导入导出 |
| GeoServer | 发布 PostGIS 图层为 WMS/WFS |
| Python | 使用 psycopg2 + shapely 或 geoalchemy2 |
| Node.js | 使用 pg + wellknown 解析 WKT |
十一、常见问题
11.1 坐标系混乱
- 始终明确 SRID
- 输入数据前验证坐标范围(如经度 -180~180,纬度 -90~90)
- 避免混用
geometry与geography
11.2 性能瓶颈
- 大表务必建空间索引
- 避免全表扫描(如未加 WHERE 条件的
ST_AsGeoJSON) - 对频繁查询区域预计算简化几何(
ST_Simplify)
11.3 数据质量
- 使用
ST_IsValid(geom)检查几何有效性 - 修复无效几何:
ST_MakeValid(geom)
总结:PostGIS 是目前最成熟、功能最全面的开源空间数据库扩展。它将 PostgreSQL 从传统关系型数据库升级为强大的地理空间分析平台。掌握其核心概念(几何 vs 地理、SRID、空间索引)和常用函数,可高效支撑 LBS、智慧城市、环境监测、物流调度等众多 GIS 应用场景。