PostGIS是什么
PostGIS是PostgreSQL数据库的空间数据库扩展。
它为PostgreSQL增加了GIS空间数据存储、空间查询、空间分析和空间索引等能力。
普通数据库主要处理:
字符串
数字
日期
JSON
数组
安装PostGIS以后,PostgreSQL还可以处理:
Point
LineString
Polygon
MultiPolygon
Raster
并且可以执行:
距离计算
面积计算
空间相交
空间包含
缓冲区分析
坐标转换
空间索引
简单来说:
PostGIS就是让PostgreSQL具备专业GIS空间数据库能力的扩展。
PostgreSQL是什么
PostgreSQL是一种开源关系型数据库。
它可以存储:
用户
订单
商品
日志
业务数据
例如:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name TEXT
);
数据库结构:
PostgreSQL
↓
Database
↓
Table
↓
Row
↓
Column
PostGIS则是在这个基础上增加空间数据能力。
PostGIS解决什么问题
传统数据库保存一个地点时,可能只保存:
longitude = 116.397
latitude = 39.908
这种方式只能简单保存坐标。
如果使用PostGIS,可以直接保存:
POINT (116.397 39.908)
并进行空间查询:
附近有哪些商店?
两个地点距离多远?
哪些道路与这个区域相交?
哪些建筑位于这个行政区?
因此:
普通数据库
↓
保存业务数据
PostGIS
↓
保存业务数据
+
空间数据
+
空间计算
+
空间查询
PostGIS的核心能力
PostGIS主要提供以下能力:
空间数据存储
空间数据查询
空间分析
空间关系判断
空间索引
坐标转换
GIS数据格式转换
可以理解为:
PostGIS
├── Spatial Data
├── Spatial Query
├── Spatial Analysis
├── Spatial Index
├── CRS
└── Data Conversion
PostGIS支持哪些空间数据
PostGIS最常见的空间数据类型包括:
Geometry
Geography
Raster
其中Geometry是最常用的矢量空间数据类型。
常见Geometry:
Point
MultiPoint
LineString
MultiLineString
Polygon
MultiPolygon
GeometryCollection
例如:
Point
↓
一个位置
LineString
↓
一条道路
Polygon
↓
一个区域
Geometry
Geometry是PostGIS中最核心的空间数据类型之一。
例如:
POINT (116.397 39.908)
可以存储到:
geometry(Point, 4326)
数据库字段:
CREATE TABLE cities (
id SERIAL PRIMARY KEY,
name TEXT,
geom geometry(Point, 4326)
);
其中:
geom
↓
Geometry
Point
↓
空间类型
4326
↓
SRID
Geography
PostGIS还提供:
Geography
它主要用于基于地球曲面进行空间计算。
例如:
POINT(116.397 39.908)
可以使用:
geography(Point, 4326)
Geometry和Geography最大的区别可以简单理解为:
Geometry
↓
平面空间计算
Geography
↓
地球曲面上的地理计算
因此进行全球范围的距离、面积等计算时,Geography有时更加方便。
Raster
PostGIS还支持Raster空间数据。
Raster主要用于:
卫星影像
遥感数据
DEM
地形数据
栅格地图
可以理解为:
Vector
↓
Point
Line
Polygon
Raster
↓
Pixel
↓
Grid
因此PostGIS不仅可以存储矢量数据,也可以处理部分栅格数据。
SRID是什么
SRID用于表示空间数据使用的坐标参考系统。
例如:
EPSG:4326
和:
EPSG:3857
都是常见的空间参考系统。
例如:
geometry(Point, 4326)
表示:
Geometry
↓
Point
↓
SRID = 4326
SRID非常重要。
如果两个Geometry使用不同的坐标参考系统,就不能简单地直接进行某些空间计算。
EPSG:4326
EPSG:4326是非常常见的地理坐标参考系统。
通常使用:
经度
纬度
例如:
116.397
39.908
可以表示:
经度 = 116.397
纬度 = 39.908
在PostGIS中:
geometry(Point, 4326)
是非常常见的定义方式。
EPSG:3857
EPSG:3857是WebGIS中非常常见的投影坐标系。
很多Web地图使用:
EPSG:3857
例如:
OpenLayers
Leaflet
Web地图Tile
经常会使用Web Mercator投影。
因此WebGIS中经常出现:
EPSG:4326
↓
ST_Transform()
↓
EPSG:3857
ST_SetSRID与ST_Transform
PostGIS中非常重要的两个函数:
ST_SetSRID
ST_Transform
ST_SetSRID:
给Geometry设置SRID
例如:
SELECT ST_SetSRID(
ST_Point(116.397, 39.908),
4326
);
它不会真正改变坐标数值。
ST_Transform:
真正进行坐标转换
例如:
SELECT ST_Transform(
geom,
3857
)
FROM cities;
因此:
ST_SetSRID
↓
设置坐标参考信息
ST_Transform
↓
转换坐标
PostGIS空间函数
PostGIS最大的优势之一就是提供大量空间函数。
例如:
ST_Distance
ST_Length
ST_Area
ST_Buffer
ST_Intersects
ST_Contains
ST_Within
ST_Intersection
ST_Union
ST_Transform
这些函数可以直接在SQL中使用。
ST_Distance
用于计算两个Geometry之间的距离。
例如:
SELECT ST_Distance(
a.geom,
b.geom
)
FROM cities a, cities b;
可以用于:
- 最近地点
- 两地距离
- 服务范围
- 距离分析
ST_Length
用于计算LineString长度。
例如:
SELECT ST_Length(geom)
FROM roads;
可以用于:
- 道路长度
- 河流长度
- 管线长度
- GPS轨迹长度
需要注意:
计算结果的单位与Geometry使用的坐标系有关。
ST_Area
用于计算Polygon面积。
例如:
SELECT ST_Area(geom)
FROM parcels;
可以用于:
- 地块面积
- 行政区面积
- 建筑面积
- 土地面积
同样需要注意坐标系和单位。
ST_Buffer
ST_Buffer用于创建缓冲区。
例如:
SELECT ST_Buffer(
geom,
100
)
FROM roads;
可以理解为:
道路
↓
100单位缓冲
↓
缓冲区域
常见应用:
- 道路影响范围
- 服务区分析
- 环境影响分析
- 安全距离
- 周边设施查询
ST_Intersects
用于判断两个Geometry是否相交。
例如:
SELECT ST_Intersects(
a.geom,
b.geom
)
FROM roads a, parcels b;
返回:
true
或者:
false
典型问题:
哪些道路经过这个地块?
就可以使用空间相交查询。
ST_Contains
用于判断一个Geometry是否包含另一个Geometry。
例如:
SELECT ST_Contains(
district.geom,
city.geom
)
FROM districts district, cities city;
典型问题:
这个城市属于哪个行政区?
可以通过空间包含关系进行判断。
ST_Within
ST_Within与ST_Contains存在相反方向的关系。
例如:
城市
↓
Within
↓
行政区
SQL:
SELECT ST_Within(
city.geom,
district.geom
);
可以判断:
city是否位于district内部
ST_Intersection
ST_Intersection用于计算两个Geometry的交集。
例如:
Polygon A
+
Polygon B
↓
Intersection
↓
交集区域
SQL:
SELECT ST_Intersection(
a.geom,
b.geom
)
FROM a, b;
常用于:
- 行政区裁剪
- 道路与区域分析
- 土地重叠分析
- 空间叠加
ST_Union
ST_Union用于合并Geometry。
例如:
Polygon A
+
Polygon B
↓
Union
↓
新的Geometry
SQL:
SELECT ST_Union(geom)
FROM parcels;
常用于:
- 区域合并
- 行政区合并
- 地块融合
- 空间数据聚合
空间索引
如果数据库中只有几十条空间数据:
100条
直接计算可能问题不大。
但如果有:
100万
1000万
个Geometry,就需要空间索引。
PostGIS常见空间索引:
GiST
例如:
CREATE INDEX idx_cities_geom
ON cities
USING GIST (geom);
这样数据库就可以利用空间索引进行高效空间查询。
为什么需要空间索引
假设有:
100万家商店
现在查询:
某个位置附近的商店。
没有空间索引:
100万
↓
逐个计算距离
有空间索引:
100万
↓
空间索引筛选
↓
少量候选对象
↓
精确计算
因此:
PostGIS
+
GiST
=
高效空间查询
PostGIS与WKT
WKT是一种空间数据文本格式。
例如:
POINT (116.397 39.908)
PostGIS可以使用:
ST_GeomFromText()
将WKT转换为Geometry。
例如:
SELECT ST_GeomFromText(
'POINT (116.397 39.908)',
4326
);
反向可以使用:
SELECT ST_AsText(geom)
FROM cities;
因此:
WKT
↓
ST_GeomFromText
↓
Geometry
以及:
Geometry
↓
ST_AsText
↓
WKT
PostGIS与WKB
WKB是Geometry的二进制表示方式。
PostGIS可以使用:
ST_AsBinary()
输出WKB。
例如:
SELECT ST_AsBinary(geom)
FROM cities;
也可以使用:
ST_GeomFromWKB()
将WKB转换为Geometry。
因此:
WKT
↓
文本
WKB
↓
二进制
Geometry
↓
PostGIS空间对象
PostGIS与GeoJSON
PostGIS可以直接生成GeoJSON。
例如:
SELECT ST_AsGeoJSON(geom)
FROM cities;
得到:
{
"type": "Point",
"coordinates": [116.397, 39.908]
}
也可以将GeoJSON转换为Geometry:
SELECT ST_GeomFromGeoJSON(
'{"type":"Point","coordinates":[116.397,39.908]}'
);
因此PostGIS非常适合WebGIS后端。
PostGIS与Shapefile
Shapefile是传统GIS中非常常见的数据格式。
可以通过GIS工具将:
Shapefile
↓
PostGIS
导入数据库。
例如:
.shp
.shx
.dbf
.prj
共同组成Shapefile数据集。
导入PostGIS以后,可以进行:
空间查询
空间分析
空间索引
数据更新
WebGIS服务
因此PostGIS经常作为Shapefile数据的数据库存储目标。
PostGIS与GeoPackage
GeoPackage是一种基于SQLite的GIS数据格式。
可以理解为:
GeoPackage
↓
SQLite
↓
GIS空间数据
而PostGIS:
PostGIS
↓
PostgreSQL
↓
GIS空间数据库
两者都可以存储:
Geometry
Attributes
Spatial Reference
但PostGIS更适合:
服务器
多人访问
大型空间数据库
WebGIS
空间查询
空间分析
PostGIS与GeoParquet
GeoParquet是一种面向分析场景的空间数据格式。
可以理解为:
GeoParquet
↓
Parquet
↓
列式存储
↓
空间数据
而PostGIS更加偏向:
数据库
↓
事务
↓
查询
↓
空间索引
↓
空间分析
两者可以配合使用。
例如:
PostGIS
↓
分析
↓
GeoParquet
↓
数据交换 / 大数据分析
PostGIS与WebGIS
PostGIS非常适合用于WebGIS后端。
典型架构:
浏览器
↓
OpenLayers / Leaflet
↓
API
↓
后端服务
↓
PostGIS
↓
PostgreSQL
例如用户在地图上点击一个区域:
用户点击地图
↓
发送坐标
↓
API
↓
PostGIS
↓
空间查询
↓
返回GeoJSON
↓
前端显示
PostGIS典型应用
PostGIS可以用于很多GIS业务。
地图服务
地图
↓
空间数据
↓
PostGIS
LBS
用户位置
↓
附近商店
附近医院
附近停车场
路网分析
道路
↓
距离
路径
连通性
城市规划
地块
建筑
道路
行政区
物流
车辆
仓库
配送点
道路
资产管理
设备
管线
建筑
设施
环境分析
河流
污染源
保护区
土地
一个简单的PostGIS示例
创建扩展:
CREATE EXTENSION postgis;
创建城市表:
CREATE TABLE cities (
id SERIAL PRIMARY KEY,
name TEXT,
geom geometry(Point, 4326)
);
插入数据:
INSERT INTO cities (name, geom)
VALUES (
'北京',
ST_SetSRID(
ST_Point(116.397, 39.908),
4326
)
);
查询WKT:
SELECT
name,
ST_AsText(geom)
FROM cities;
结果:
北京
POINT(116.397 39.908)
输出GeoJSON:
SELECT
name,
ST_AsGeoJSON(geom)
FROM cities;
创建空间索引:
CREATE INDEX idx_cities_geom
ON cities
USING GIST (geom);
这就是一个最基本的PostGIS空间数据流程。
PostGIS完整数据流程
一个典型的GIS数据进入PostGIS的过程:
Shapefile
GeoJSON
WKT
CSV
GeoPackage
↓
数据导入
↓
PostGIS
↓
Geometry
↓
SRID
↓
空间索引
↓
空间查询
↓
空间分析
↓
GeoJSON
↓
WebGIS
PostGIS数据架构
可以从三个层次理解PostGIS:
PostgreSQL
↓
数据库能力
│
├── Table
├── SQL
├── Transaction
└── Index
↓
PostGIS
↓
空间能力
│
├── Geometry
├── Geography
├── Spatial Function
├── Spatial Index
└── CRS
↓
GIS应用
│
├── WebGIS
├── LBS
├── 地图服务
├── 空间分析
└── 数据管理
PostGIS与普通数据库的区别
| 能力 | PostgreSQL | PostgreSQL + PostGIS |
|---|---|---|
| 普通数据 | 支持 | 支持 |
| JSON | 支持 | 支持 |
| Geometry | 不属于核心能力 | 支持 |
| Geography | 不支持 | 支持 |
| 空间索引 | 不支持 | 支持 |
| 空间距离 | 不支持 | 支持 |
| 空间相交 | 不支持 | 支持 |
| 空间缓冲 | 不支持 | 支持 |
| 坐标转换 | 不支持 | 支持 |
| GIS分析 | 有限 | 强大 |
因此:
PostGIS不是一个独立的数据库,而是PostgreSQL的GIS空间扩展。
PostGIS与传统GIS软件
传统GIS软件:
QGIS
ArcGIS
更偏向:
桌面GIS
地图制作
数据编辑
空间分析
PostGIS更偏向:
空间数据库
数据存储
空间查询
多人访问
WebGIS后端
服务端空间分析
实际项目中经常组合使用:
QGIS
↓
编辑GIS数据
↓
PostGIS
↓
保存空间数据
↓
WebGIS
↓
OpenLayers
PostGIS知识结构
可以这样理解:
PostGIS
├── PostgreSQL
│
├── Spatial Data
│ ├── Geometry
│ ├── Geography
│ └── Raster
│
├── CRS
│ ├── EPSG:4326
│ └── EPSG:3857
│
├── Spatial Functions
│ ├── Distance
│ ├── Length
│ ├── Area
│ ├── Buffer
│ ├── Intersection
│ ├── Union
│ └── Spatial Relations
│
├── Spatial Index
│ └── GiST
│
├── Data Formats
│ ├── WKT
│ ├── WKB
│ ├── GeoJSON
│ ├── Shapefile
│ └── GeoPackage
│
└── Applications
├── WebGIS
├── LBS
├── 地图服务
└── 空间分析
PostGIS与GIS知识体系
PostGIS在整个GIS知识体系中可以放在:
GIS
│
├── 数据
│ ├── Vector
│ ├── Raster
│ └── Tile
│
├── 数据格式
│ ├── Shapefile
│ ├── GeoJSON
│ ├── WKT
│ ├── WKB
│ ├── GeoPackage
│ └── GeoParquet
│
├── 坐标系统
│ ├── CRS
│ ├── EPSG:4326
│ └── EPSG:3857
│
├── 空间分析
│ ├── Buffer
│ ├── Distance
│ ├── Intersection
│ └── Spatial Relation
│
└── 空间数据库
└── PostGIS
总结
PostGIS是PostgreSQL的空间数据库扩展。
它让PostgreSQL能够直接存储和处理GIS空间数据。
核心能力包括:
Geometry
Geography
Raster
CRS
空间函数
空间索引
可以进行:
距离计算
长度计算
面积计算
缓冲区分析
相交分析
包含判断
空间集合运算
坐标转换
同时可以与:
WKT
WKB
GeoJSON
Shapefile
GeoPackage
GeoParquet
等GIS数据格式进行数据交换。
在WebGIS中,一个典型架构是:
PostGIS
↓
空间查询
↓
API
↓
GeoJSON
↓
OpenLayers / Leaflet
↓
地图
最终可以记住:
PostGIS = PostgreSQL + GIS空间数据 + 空间索引 + 空间查询 + 空间分析。
相关工具
使用 IYATools 在线工具快速处理 GIS 数据