几何(geometry)对象类型
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);
另外要注意的是,空间索引只有在进行基于边界范围的查询时才起作用,比如“&&”操作。
更多建议: