几何(geometry)对象类型

2018-08-02 17:18 更新

OGC的WKB和WKT格式

OGC定义了两种描述几何对象的格式,分别是WKB(Well-Known Binary)和WKT(Well-Known Text)。 在SQL语句中,用以下的方式可以使用WKT格式定义几何对象:

几何要素 WKT格式

点 POINT(0 0) 线 LINESTRING(0 0,1 1,1 2) 面 POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1)) 多线 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)))

以下语句可以使用WKT格式插入一个点要素到一个表中,其中用到的GeomFromText等函数在后面会有详细介绍:

INSERT INTO table (SHAPE,NAME) VALUES (GeomFromText('POINT(116.39 39.9)', 4326), '北京');

EWKT、EWKB和Canonical格式

EWKT和EWKB相比OGC WKT和WKB格式主要的扩展有3DZ、3DM、4D坐标和内嵌空间参考支持。 以下以EWKT语句定义了一些几何对象:

几何类型 格式 3D点 POINT(0 0 0) 内嵌空间参考的点 SRID=32632;POINT(0 0) 带M值的点 POINTM(0 0 0) 带M值的3D点 POINT(0 0 0 0) 内嵌空间参考的带M值的多点 SRID=4326;MULTIPOINTM(0 0 0,1 2 1)

以下语句可以使用EWKT格式插入一个点要素到一个表中:

INSERT INTO table (SHAPE, NAME) VALUES(GeomFromEWKT('SRID=4326;POINTM(116.39 39.9 10)'), '北京')

Canonical格式是16进制编码的几何对象,直接用SQL语句查询出来的就是这种格式。

SQL-MM格式

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

几何类型 格式 插值圆弧 CIRCULARSTRING(0 0, 1 1, 1 0) 插值复合曲线 COMPOUNDCURVE(CIRCULARSTRING(0 0, 1 1, 1 0),(1 0, 0 1)) 曲线多边形 CURVEPOLYGON(CIRCULARSTRING(0 0, 4 0, 4 4, 0 4, 0 0),(1 1, 3 3, 3 1, 1 1)) 多曲线 MULTICURVE((0 0, 5 5),CIRCULARSTRING(4 0, 4 4, 8 4)) 多曲面 MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING(0 0, 4 0, 4 4, 0 4, 0 0),(1 1, 3 3, 3 1, 1 1)),((10 10, 14 12, 11 10, 10 10),(11 11, 11.5 11, 11 11.5, 11 11)))

PostGIS中空间信息处理的实现

spatial_ref_sys表

在基于PostGIS模板创建的数据库的public模式下,有一个spatial_ref_sys表,它存放的是OGC规范的空间参考。

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

geometry_columns表

geometry_columns表存放了当前数据库中所有几何字段的信息,比如我当前的库里面有两个空间表,在geometry_columns表中就可以找到这两个空间表中几何字段的定义 其中f_table_schema字段表示的是空间表所在的模式,f_table_name字段表示的是空间表的表名,f_geometry_column字段表示的是该空间表中几何字段的名称,srid字段表示的是该空间表的空间参考。

在PostGIS中创建一个空间表

在PostGIS中创建一个包含几何字段的空间表分为2步:第一步创建一个一般表,第二步给这个表添加几何字段。

以下先在test模式下创建一个名为cities的一般表:

create table test.cities (id int4, name varchar(20))

再给cities添加一个名为shape的几何字段(二维点):

select AddGeometryColumn('test', 'cities', 'shape', 4326, 'POINT', 2)

PostGIS对几何信息的检查

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

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

PostGIS中的空间索引

数据库对多维数据的存取有两种索引方案,R-Tree和GiST(Generalized Search Tree),在PostgreSQL中的GiST比R-Tree的健壮性更好,因此PostGIS对空间数据的索引一般采用GiST实现。

以下的语句给sde模式中的cities表添加了一个空间索引shape_index_cities,在pgAdmin中也可以通过图形界面完成相同的功能。

CREATE INDEX shape_index_cities ON sde.cities USING gist (shape);

另外要注意的是,空间索引只有在进行基于边界范围的查询时才起作用,比如“&&”操作。

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号