强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

PostGIS 完全指南 / 第 1 章:PostGIS 简介

第 1 章:PostGIS 简介

1.1 什么是 PostGIS

PostGIS 是 PostgreSQL 的空间数据库扩展,它为 PostgreSQL 添加了对地理空间对象的支持。通过 PostGIS,你可以在关系型数据库中存储、查询和分析地理空间数据,将传统的关系数据与空间数据无缝结合。

核心能力

能力 说明 示例函数
空间数据存储 存储点、线、面等几何对象 ST_GeomFromText()
空间关系判断 判断几何对象之间的拓扑关系 ST_Intersects(), ST_Contains()
空间测量 计算距离、面积、长度 ST_Distance(), ST_Area()
空间分析 缓冲区、叠加、融合等分析操作 ST_Buffer(), ST_Union()
坐标转换 不同坐标系之间的转换 ST_Transform()
栅格数据 支持栅格(raster)数据存储与分析 ST_MapAlgebra()
拓扑建模 支持拓扑数据模型 Topology 类型

版本历史与里程碑

版本 年份 关键特性
1.0 2001 首次发布,基础几何类型
2.0 2012 引入 Geography 类型、栅格支持
3.0 2019 性能大幅提升、并行查询支持
3.4 2023 改进的 3D 支持、增强的 GeoJSON 处理
-- 查看当前 PostGIS 版本
SELECT PostGIS_Version();
-- 输出示例: 3.4 USE_GEOS=1 USE_PROJ=1 USE_STATS=1

1.2 OGC 标准与 Simple Features

OGC(Open Geospatial Consortium,开放地理空间联盟)是一个国际标准化组织,制定了地理空间数据的互操作标准。PostGIS 实现了 OGC 的 Simple Feature Access (SFA) 规范。

Simple Feature 模型

SFA 规范定义了以下核心几何类型:

Geometry (抽象基类)
├── Point                    -- 点
├── LineString               -- 线
├── Polygon                  -- 面
├── MultiPoint               -- 多点集合
├── MultiLineString          -- 多线集合
├── MultiPolygon             -- 多面集合
└── GeometryCollection       -- 混合几何集合

Well-Known Text (WKT) 表示

SFA 规范定义了几何对象的文本表示格式——WKT(Well-Known Text):

-- 点 (Point)
SELECT ST_GeomFromText('POINT(116.4074 39.9042)');  -- 北京天安门

-- 线 (LineString)
SELECT ST_GeomFromText('LINESTRING(116.40 39.90, 116.42 39.92, 116.44 39.91)');

-- 面 (Polygon) — 注意首尾坐标相同,形成闭合环
SELECT ST_GeomFromText('POLYGON((116.38 39.90, 116.42 39.90, 116.42 39.93, 116.38 39.93, 116.38 39.90))');

-- 多面 (MultiPolygon)
SELECT ST_GeomFromText('MULTIPOLYGON(((0 0, 1 0, 1 1, 0 1, 0 0)), ((2 2, 3 2, 3 3, 2 3, 2 2)))');

Well-Known Binary (WKB)

WKB 是几何对象的二进制表示,适合程序间高效传输:

-- 输出 WKB 的十六进制表示
SELECT ST_AsHexEWKB(ST_GeomFromText('POINT(116.4074 39.9042)'));

-- 从 WKB 创建几何
SELECT ST_GeomFromEWKB('\x01010000005839b4c876be5d407b14ae47e1524340');

注意: WKT 和 WKB 是 PostGIS 中最基础的两种数据格式,几乎所有操作都围绕它们展开。


1.3 空间数据库 vs 文件型 GIS

传统 GIS 使用 Shapefile、GeoJSON 等文件格式存储空间数据。空间数据库则将数据纳入关系型数据库管理体系。

对比表

特性 文件型 GIS (Shapefile) 空间数据库 (PostGIS)
并发访问 不支持 完整 ACID 事务支持
数据量级 单文件约 2GB 无硬性限制(TB 级)
空间查询 需加载到内存 索引加速,按需查询
属性查询 有限 SQL 支持 完整 SQL 支持
数据关联 需要额外处理 与业务表 JOIN
版本控制 文件复制 数据库备份与恢复
安全控制 文件权限 行级安全策略 (RLS)
扩展性 支持分区、复制、集群

典型架构

┌──────────────┐     ┌──────────────────┐     ┌──────────────┐
│  前端应用     │────▶│   PostGIS 数据库  │────▶│  空间分析引擎  │
│  (Leaflet等)  │     │  (PostgreSQL)     │     │  (GEOS/PROJ)  │
└──────────────┘     └──────────────────┘     └──────────────┘
        │                    │                        │
        ▼                    ▼                        ▼
   GeoJSON API         SQL 查询               拓扑/投影计算

1.4 PostGIS 生态系统

PostGIS 不是孤立的,它与一系列开源工具组成了强大的空间数据生态:

核心依赖库

功能 PostGIS 中的角色
GEOS 几何引擎 几何操作的底层实现(交集、缓冲区等)
PROJ 坐标投影库 坐标系统转换
GDAL 栅格数据抽象库 栅格数据读写
SFCGAL 高级几何库 3D 操作、高级拓扑运算
CGAL 计算几何库 SFCGAL 的后端

相关工具链

-- 查看 PostGIS 编译时的依赖支持
SELECT name, default_version, installed_version
FROM pg_available_extensions
WHERE name IN ('postgis', 'postgis_topology', 'postgis_raster',
               'pgrouting', 'address_standardizer', 'postgis_sfcgal');
工具 用途
shp2pgsql / pgsql2shp Shapefile 导入导出
ogr2ogr (GDAL) 多格式空间数据转换
raster2pgsql 栅格数据导入
pgRouting 路径规划扩展
pg_tileserv 矢量瓦片服务
pg_featureserv OGC API - Features 服务

1.5 适用场景与不适用场景

✅ 推荐使用 PostGIS 的场景

场景 1:位置服务(LBS)

  • 附近的人/店铺搜索
  • 地理围栏(Geofencing)判断
  • 配送范围计算
-- 查找某点 3 公里范围内的所有门店
SELECT name, address,
       ST_Distance(
         geom::geography,
         ST_SetSRID(ST_MakePoint(116.4074, 39.9042), 4326)::geography
       ) AS distance_m
FROM stores
WHERE ST_DWithin(
  geom::geography,
  ST_SetSRID(ST_MakePoint(116.4074, 39.9042), 4326)::geography,
  3000
)
ORDER BY distance_m;

场景 2:城市规划与管理

  • 地块叠加分析
  • 基础设施覆盖分析
  • 人口密度热力图

场景 3:物流与运输

  • 路径优化
  • 车辆追踪
  • 仓储选址分析

场景 4:环境与自然资源

  • 土地利用变化监测
  • 洪水淹没分析
  • 生态保护区管理

场景 5:商业智能

  • 市场区域划分
  • 竞品地理分布分析
  • 销售热区识别

❌ 不推荐使用 PostGIS 的场景

场景 替代方案 原因
海量实时轨迹流 TimescaleDB + PostGIS 或 MongoDB 高频写入压力大
瓦片地图渲染 MapServer / GeoServer 数据库不是最优的渲染引擎
卫星影像处理 Google Earth Engine / Rasterio 专业工具更高效
简单坐标存储 MongoDB 2dsphere / Redis GEO 轻量方案更简单
超大规模图计算 Neo4j Spatial / Apache Spark 图数据库更适合关系遍历

1.6 第一个空间查询

让我们通过一个完整的示例来感受 PostGIS 的能力。

创建示例表

-- 创建城市表
CREATE TABLE cities (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    province VARCHAR(50),
    population INTEGER,
    geom GEOMETRY(Point, 4326)
);

-- 插入示例数据
INSERT INTO cities (name, province, population, geom) VALUES
('北京', '北京', 21890000, ST_SetSRID(ST_MakePoint(116.4074, 39.9042), 4326)),
('上海', '上海', 24870000, ST_SetSRID(ST_MakePoint(121.4737, 31.2304), 4326)),
('广州', '广东', 18680000, ST_SetSRID(ST_MakePoint(113.2644, 23.1291), 4326)),
('深圳', '广东', 17560000, ST_SetSRID(ST_MakePoint(114.0579, 22.5431), 4326)),
('成都', '四川', 20940000, ST_SetSRID(ST_MakePoint(104.0668, 30.5728), 4326)),
('杭州', '浙江', 12200000, ST_SetSRID(ST_MakePoint(120.1551, 30.2741), 4326)),
('武汉', '湖北', 12330000, ST_SetSRID(ST_MakePoint(114.3055, 30.5928), 4326)),
('西安', '陕西', 13000000, ST_SetSRID(ST_MakePoint(108.9402, 34.2613), 4326));

-- 创建空间索引
CREATE INDEX idx_cities_geom ON cities USING GIST (geom);

执行空间查询

-- 查询 1:计算北京到上海的直线距离(米)
SELECT ST_Distance(
    (SELECT geom FROM cities WHERE name = '北京')::geography,
    (SELECT geom FROM cities WHERE name = '上海')::geography
) / 1000 AS distance_km;
-- 输出: ~1068 公里

-- 查询 2:查找北京 1500 公里范围内的城市
SELECT name, province, population,
       ROUND(ST_Distance(geom::geography,
             ST_SetSRID(ST_MakePoint(116.4074, 39.9042), 4326)::geography
       ) / 1000) AS distance_km
FROM cities
WHERE ST_DWithin(
    geom::geography,
    ST_SetSRID(ST_MakePoint(116.4074, 39.9042), 4326)::geography,
    1500000
)
ORDER BY distance_km;

-- 查询 3:生成 GeoJSON 输出
SELECT jsonb_build_object(
    'type', 'FeatureCollection',
    'features', jsonb_agg(
        jsonb_build_object(
            'type', 'Feature',
            'geometry', ST_AsGeoJSON(geom)::jsonb,
            'properties', jsonb_build_object(
                'name', name,
                'province', province,
                'population', population
            )
        )
    )
) AS geojson
FROM cities;

1.7 关键术语表

术语 英文 说明
几何类型 Geometry Type 点、线、面等空间对象类型
地理类型 Geography Type 基于球面的地理坐标类型
空间参考系统 Spatial Reference System (SRS) 坐标系统的标准化定义
SRID Spatial Reference System Identifier 空间参考系统的唯一标识符
WKT Well-Known Text 几何对象的文本表示格式
WKB Well-Known Binary 几何对象的二进制表示格式
拓扑关系 Topological Relation 几何对象之间的空间关系(相交、包含等)
缓冲区 Buffer 距某几何对象指定距离的区域
叠加分析 Overlay Analysis 两个图层的空间叠加运算
空间索引 Spatial Index 加速空间查询的索引结构

1.8 本章小结

要点 说明
PostGIS 是什么 PostgreSQL 的空间扩展,实现 OGC SFA 规范
核心能力 空间存储、查询、分析、坐标转换
数据格式 WKT(文本)和 WKB(二进制)
适用场景 LBS、城市规划、物流、环境监测、商业智能
生态系统 GEOS + PROJ + GDAL + pgRouting 等

扩展阅读