PostGreSQL(四)PostGIS-空间数据存储

空间数据存储

使用geography这种数据类型时,PostGIS的内部计算是基于实际地球球体来计算的;而使用geometry这种数据类型时,PostGIS的内部计算是基于平面来计算的。

几何类型(Geometry Type)

Geometry(几何对象类型)是PG的一个基本存储类型,PostGIS的空间数据都会以Geometry的形式存储在PostgreSQL里,本质是个二进制对象。

OGC的WKB和WKT格式

PostGIS基于OGC的“Simple Feature for Specification for SQL”规范,在Geometry对象上实现了一系列的GIS Object(地物对象),使用了OGC推荐的WKT(Well-Known Text)和WKB(Well-Known Binary)格式进行描述,大幅增加了易用性,例如WKT的7个基本类型:

点:POINT(0 0)

线:LINESTRING(0 0,1 1,1 2)

面(多边形):POLYGON((0 0,4 0,4 4,0 4,0 0)) 简单多边形
POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1)) 多边形有一个内部的"孔洞(hole)"

多点:MULTIPOINT((0 0),(1 2))

多线:MULTILINESTRING((0 0,1 1,1 2),(2 3,3 2,5 4))

多面:MULTIPOLYGON(((0 0,4 0,4 4,0 4,0 0),(1 1,2 1,2 2,1 2,1 1)), ((-1 -1,-1 -2,-2 -2,-2 -1,-1 -1)))

几何集合:GEOMETRYCOLLECTION(POINT(2 3),LINESTRING(2 3,3 4))
EWKT、EWKB和Canonical格式

PostGIS自身又在WKT和WKB基础上扩展实现了EWKT和EWKB来满足更复杂的场景需求,EWKT和EWKB相比OGC WKT和WKB格式主要的扩展有3DZ、3DM、4D坐标和内嵌空间参考支持

SQL-MM格式

SQL-MM格式定义了一些插值曲线,这些插值曲线和EWKT有点类似,也支持3DZ、3DM、4D坐标,但是不支持嵌入空间参考。

地理类型(Geography Type)

地理类型提供支持本地空间特性的“地理”坐标(有时称为“大地”坐标,或“纬度/经度”,或“经度/纬度”)。它的几何基础是球面。计算两点间的距离相当于计算圆弧的距离,不能使用平面几何原理,需要通过其他参考方法计算。由于底层算法复杂,定义的地理类型比空间类型少很多,随之算法的增加,将出现新的地理类型。

PostGresSQL8.3推出一张表辅助空间参考表:spatial_ref_sys表,它存放的是OGC规范的空间参考。辅助转化。 地理类型只支持简单的简单的元素。标准几何类型数据将自动转换到地理WGS84坐标。还可以使用EWKT和EWKB约定来插入数据。

patial_ref_sys表,它存放的是OGC规范的空间参考。我们取我们最熟悉的4326参考看一下:

它的srid存放的就是空间参考的Well-Known ID,对这个空间参考的定义主要包括两个字段,srtext存放的是以字符串描述的空间参考,proj4text存放的则是以字符串描述的PROJ.4 投影定义(PostGIS使用PROJ.4实现投影)

SRID 4326声明了地理空间参考系统

如下创建表:

CREATE TABLE global_points (
id SERIAL PRIMARY KEY,
name VARCHAR(64),
location GEOGRAPHY(POINT,4326)
);

插入数据:

INSERT INTO global_points (name, location) VALUES 
('London', ST_GeographyFromText('SRID=4326; POINT(-72.1235 42.3521)'));

PostGIS对几何信息的检查

PostGIS可以检查几何信息的正确性,这主要是通过IsValid函数实现的。 以下语句分辨检查了2个几何对象的正确性,显然,(0, 0)点和(1,1)点可以构成一条线,但是(0, 0)点和(0, 0)点则不能构成,这个语句执行以后的得出的结果是TRUE,FALSE。

select IsValid('LINESTRING(0 0, 1 1)'), IsValid('LINESTRING(0 0,0 0)')

默认PostGIS并不会使用IsValid函数检查用户插入的新数据,因为这会消耗较多的CPU资源(特别是复杂的几何对象)。当你需要使用这个功能的时候,你可以使用以下语句为表新建一个检查约束:

ALTER TABLE cities
ADD CONSTRAINT geometry_valid CHECK (IsValid(shape))

这时当我们往这个表试图插入一个错误的空间对象的时候,会得到一个错误:

INSERT INTO test.cities ( shape, name )
VALUES ( GeomFromText('LINESTRING(0 0,0 0)', 4326), '北京');
ERROR: new row for relation "cities" violates check constraint "geometry_valid"
SQL 状态: 23514

 

 

posted @ 2020-10-28 20:38  hjy1995  阅读(6667)  评论(0编辑  收藏  举报