PostgreSQL 中的 ST_Geometry 存储
ArcSDE for PostgreSQL 支持的几何存储类型必须通过符合国际标准化组织 (ISO) 和开放地理空间联盟 (OGC) 标准的结构化查询语言 (SQL) 访问地理数据库。这些存储类型包括 ST_Geometry 和 PostGIS 几何。通过向表示地理要素的对象(点、线和面)提供存储空间,这两种存储类型使 PostgreSQL 数据库的功能得以扩展。借助这两种存储类型,可以将空间数据同其他类型的商业数据进行集成,从而使多用户数据库通过将地理组件添加到分析和数据产品而从中受益。将空间数据与其他业务对象一起存储还可简化数据的多用户访问、管理并增强安全性,因为这样做减少了要管理的数据存储资源。
默认情况下,PostgreSQL 中的 ArcSDE 地理数据库使用 ST_Geometry 空间类型。该数据库遵循用户定义数据类型 (UDT) 的 SQL 3 规范,用于创建可存储空间数据(如地标、街道或土地宗地的位置)的列。有关 ST_Geometry 空间类型的说明,请参阅什么是 ST_Geometry 存储类型?。
在 PostgreSQL 中的地理数据库内使用 ST_Geometry 空间类型,便可使用遵循 ISO SQL/MM 空间标准和 OGC 简单要素规范的 SQL 函数来访问空间数据。您便可以使用 SQL 命令像处理任何其他类型的数据那样存储、检索及操作空间要素。通过 SQL 命令及存储过程可使用一长串标准化的函数来检索和分析空间数据。通过 SQL 访问数据,用户便可以使用其他应用程序来访问在 PostgreSQL 中的地理数据库内创建的数据。
本主题将介绍如下内容
- 应用于 PostgreSQL 中 ArcSDE 地理数据库时的空间类型架构
- 如何使用 ST_Geometry 存储类型存储要素类
- sde_coordinate_system 表中的记录
- 相关文档所在位置
要了解如何使用 SQL 对采用 ST_Geometry 存储的表进行处理,请参阅以下主题:
- 创建包含 ST_Geometry 列的表
- 向包含 ST_Geometry 列的表中插入要素
- 查询包含 ST_Geometry 列的表
- 使用 SQL 更新 ST_Geometry 空间列中的值
- 针对包含 ST_Geometry 列的表应用空间视图
有关 PostGIS 几何类型的信息,请参阅什么是 PostGIS 几何类型?。
ST_Geometry 如何存储空间数据
以下是有关 PostgreSQL 中 ST_Geometry 的描述:
名称 |
类型 |
描述 |
---|---|---|
大小 |
LONG INTEGER |
ST_Geometry 结构的总长度(包括形状缓冲区) |
srid |
LONG INTEGER |
包含几何的标识符,用于将几何链接到与之关联的 sde_spatial_references 表中的空间参考(坐标系)记录 |
numpts |
LONG INTEGER |
定义几何的点数;对于多部分 (multipart) 几何,还包括各个部分之间的分隔符,每个分隔符对应一个点。 |
entity |
SHORT INTEGER |
存储在空间列中的几何要素类型(线串、多线串、多点、多面、点或面),其值为从 st_geom_util 存储过程获得的位掩码。 |
sqltype |
SHORT INTEGER |
形状的 SQL 类型;例如,POINT_TYPE、POINTM_TYPE 或 MULTIPOLYGONZM_TYPE |
minx |
LFLOAT |
与 miny、maxx 和 maxy 一同定义几何的空间包络矩形 |
miny |
LFLOAT |
与 minx、maxx 和 maxy 一同定义几何的空间包络矩形 |
maxx |
LFLOAT |
与 minx、miny 和 maxy 一同定义几何的空间包络矩形 |
maxy |
LFLOAT |
与 minx、miny 和 maxx 一同定义几何的空间包络矩形 |
minz |
LFLOAT |
最小 z 值 |
maxz |
LFLOAT |
最大 z 值 |
minm |
LFLOAT |
最小测量值 |
maxm |
LFLOAT |
最大测量值 |
area |
LFLOAT |
几何面积 |
len |
LFLOAT |
几何周长 |
shape |
BYTEA |
ESRI 压缩形状 |
与其他对象类型一样,ST_Geometry 数据类型包含一个构造函数方法和多个函数。构造函数方法是一种可返回数据类型的新实例(对象)并设置其属性值的函数。
构造函数名与类型 (ST_Geometry) 名相同。在实例化 ST_Geometry 类型对象时,可调用构造函数方法,如下例所示:
CREATE TABLE hazardous_sites (name varchar(128), location st_geometry);
以下是 ST_Geometry 存取器函数的调用示例,这些函数将单个 ST_Geometry 作为输入并以数字形式返回请求的属性值。
- ST_Area 成员函数返回几何体的面积。
- ST_Len 返回几何体的长度。
- ST_Entity 返回一个包含位掩码(该位掩码描述了实体类型)的数字。
- ST_NumPoints 返回定义几何的点(折点)数。
- ST_MinM、ST_MinX、ST_MinY 和 ST_MinZ 返回几何所需的最小坐标。
- ST_MaxM、ST_MaxX、ST_MaxY 和 ST_MaxZ 返回几何所需的最大坐标。
- ST_SRID 返回几何的空间参考标识符。
例如,以下查询可返回美国各个州的名称和面积。
SELECT name, st_area(geometry) FROM us_states ORDER BY name;
ST_LineString、ST_MultiLineString、ST_MultiPoint、ST_MultiPolygon、ST_Point 和 ST_Polygon 均为 ST_Geometry 的子类型(或子类)。ST_Geometry 及其子类型共享通用属性与函数。ST_LineString、ST_MultiLineString、ST_MultiPoint、ST_MultiPolygon、ST_Point 和 ST_Polygon 的构造函数定义是相同的。构造函数名与其构造的类型名相同。
元数据模式
PostgreSQL 类型的空间类型和元数据表均存储在 sde 方案中。方案定义是元数据表的基表描述,这些元数据表用于定义和描述列/表类型、空间索引和空间参考信息。
有关各个表的说明,请参阅在存储在 PostgreSQL 中的地理数据库的系统表中列出的表。这些表包括 st_coordinate_systems、st_units_of_measure、sde_geometry_columns、sde_spatial_references 和 sde_coordinate_system。
在 ArcGIS 中使用 ST_Geometry 存储创建要素类
首次安装 ArcSDE for PostgreSQL 时,ST_Geometry 是通过 ArcGIS Desktop 或 sdelayer 命令创建要素类时所使用的默认几何存储类型。ArcSDE 存储的默认设置是通过 DEFAULTS 配置关键字的 GEOMETRY_STORAGE 参数在 sde_dbtune 表中进行定义的。如果您未更改 DEFAULTS 关键字的 GEOMETRY_STORAGE 参数值,除非您在创建要素类时指定已将 GEOMETRY_STORAGE 设置为 PG_GEOMETRY 的其他配置关键字,否则所有要素类均会使用 ST_Geometry 存储来创建。
如果您决定要将 DEFAULTS GEOMETRY_STORAGE 参数更改为 PG_GEOMETRY(表示 PostGIS 所使用的空间类型),则可以为 ST_Geometry 存储创建一个新的配置关键字。例如,可以按如下方式创建配置关键字:
##ST_GEOMETRY GEOMETRY_STORAGE "ST_GEOMETRY" UI_TEXT "User-interface for ST_GEOMETRY keyword" END
使用 sdedbtune 命令将值更改或添加到 sde_dbtune 表。有关说明,请参阅创建 DBTUNE 表后更改其内容。
在同一数据库中,PostGIS 存储类型和 ST_Geometry 存储类型可以同时使用。虽然默认的几何存储类型只能有一种,但创建各表时允许使用不同的几何存储类型。因此,即使将默认 GEOMETRY_STORAGE 更改为 PG_GEOMETRY,创建某些要素类时仍可使用 ST_GEOMETRY 存储类型,您只需指定与上述关键字相同的关键字即可。
创建使用 ST_GEOMETRY 类型 GEOMETRY_STORAGE 的要素类时,该要素类的业务表将带有一个 ST_Geometry 类型列,并且要素类的空间数据将存储在该列中。
使用包含 ST_Geometry 列的现有 PostgreSQL 表
如果创建包含 ST_Geometry 列的表时使用的是 SQL,则将该表注册到 ArcSDE 所需满足的条件如下所示:
- 表必须归注册此表的用户所有。
- 必须具有单个 ST_Geometry 列。
- 必须没有属于用户定义类型的其他列。
- 几何类型必须单一(点、线或面),但几何可以为多部分 (multipart)(多点、多线串、多面)。
- 表中所有记录必须使用相同的空间参考。
表中还必须包含一个可用作行 ID 列的唯一的整数型非空列。该列可以在将表注册到 ArcSDE 之前添加,也可以在注册过程中添加。
此外,该表还应当拥有一个空间索引。您可以在将该表注册到 ArcSDE 之前或之后使用 SQL 添加空间索引。
创建包含 ST_Geometry 列的表
在下例中,将使用 SQL 创建了一个包含 ST_Geometry 列 shape 的表 blocks。
CREATE TABLE sasha.blocks (objectid integer NOT NULL, block varchar(4), res smallint, shape st_geometry) WITHOUT OIDS;
为表创建空间索引
ArcSDE for PostgreSQL 使用通用搜索树 (GiST) 索引。并将使用包含 gist 访问方法和 st_geometry_ops 运算符类的 CREATE INDEX 语句为表的 ST_Geometry 列创建索引。例如:
CREATE INDEX blockssp_idx ON blocks USING gist(zone st_geometry_ops);
将表注册到 ArcSDE
如果存在包含 ST_Geometry 列的表且该表已具有空间索引,就可以使用 sdelayer –o register 命令将该表注册到 ArcSDE。将表注册到 ArcSDE 后,即可为 sde_layers、sde_table_registry 和 sde_geometry_columns 系统表中的表添加记录。另外,记录还将添加到 sde_column_registry 系统表中的每列。
sdelayer –o register –l blocks,shape –e a –C objectid,SDE –R 5 –t ST_GEOMETRY – s myserver –i sde:postgresql:myserver –D mycitydb –u sasha –p super1
对于包含大量记录的表,如果将行 ID 列注册为用户维护,则注册时间会缩短。
sdelayer –o register –l blocks,shape –e a –C objectid,USER –t ST_GEOMETRY –s myserver –i sde:postgresql:myserver –D mycitydb –u sasha –p super1
但是,如果将要素标识符列注册为用户维护,然后将要素类注册到地理数据库,则 ArcGIS 会再添加一个要素标识符列 object_ID。并且将由 ArcGIS 维护此列的值。如果此表包含大量记录,添加此 object_ID 列可能需要一些时间。
倘若您已经对空间列进行过注册并已使用 st_register_spatial_column 功能为表指定了一个空间参考 ID (SRID),便无需使用 sdelayer 命令来指定 SRID。不过,如果您尚未为表分配 SRID,则必须使用 –R 选项来指定一个有效的 SRID,如下例所示:
sdelayer –o register –l infestations,site –e p+ –C siteid,SDE –s myserver –t ST_GEOMETRY –R 3 –i sde:postgresql:myserver –D meddb –u blorca –p it.s.me
如本主题中前文所述,如果 sde_spatial_references 表中不存在所需空间参考,则可在 ArcCatalog 中创建一个使用所需空间参考的模板要素类,然后通过查询 sde_spatial_references 表来查看为该表分配了哪个 SRID。这便是您在同一个坐标参照系中注册其他空间表时所使用的 SRID 号。
如果您未使用 st_register_spatial_column 功能为空间列注册 SRID,并且在将表注册到 ArcSDE 时也未使用 –R 选项指定一个 SRID,则会使用第一条记录的 SRID。如果您未使用 st_register_spatial_column 功能为空间列注册 SRID 且表为空,则会使用数值为 0 的 SRID。数值为 0 的 SRID 仅作采样和存档之用,不建议用于生产数据。此 SRID 的详细描述如下:
falsex |
- 400 |
falsey |
- 400 |
xyunits |
1000000000 |
falsez |
- 100000 |
zunits |
10000 |
falsem |
- 100000 |
munits |
10000 |
xycluster_tol |
0.000000008983153 |
zcluster_tol |
.001 |
mcluster_tol |
.001 |
srtext |
GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]], PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]] |
cs_id |
4326 |
organization |
EPSG |
有关 sdelayer 命令的完整语法和说明,请查阅随 ArcGIS Server Enterprise 提供的《ArcSDE 管理命令参考》。
通过 sdelayer 命令只能将此表添加至 ArcSDE 系统表。要顺利使用 ArcGIS Desktop 地理数据库功能(例如拓扑、版本管理和网络),还必须将表注册到地理数据库。有关详细信息,请参阅将表注册到地理数据库和注册包含空间列的第三方表。
提示
- 您可以通过执行 sde.st_register_spatial_column 功能在包含 ST_Geometry 列的表中注册空间列。这样便可为表分配指定的 SRID,从而防止用户在通过 SQL 插入数据时指定其他 SRID。
SELECT st_register_spatial_column( '<database_name>', '<schema_name>', '<table_name>', '<spatial_column_name>', <srid>)
SELECT st_register_spatial_column( 'mycitydb', 'sasha', 'blocks', 'shape', 4)
- 要取消注册某个空间列,您可以执行 st_unregister_spatial_column() 功能。此功能取消注册空间列的方法是,将某个空间列从 sde_geometry_columns 系统表中移除,这样该空间列便不再与任何空间参考系统关联。
SELECT st_unregister_spatial_column( '<database_name>', '<schema_name>', '<table_name>', '<column_name>')
- 您可以通过执行 st_isregistered_spatial_column 功能来检查某个空间列是否已经注册。
SELECT st_isregistered_spatial_column( '<database_name>', '<schema_name>', '<table_name>', '<column_name>', <srid>)
sde_coordinate_systems 表中的记录
SDE 方案中的 sde_coordinate_systems 表用于存储数据库中所用坐标系的 ID 和描述。创建地理数据库后,该表中将填满坐标系。
您可以将该表中的坐标系应用于通过 ArcGIS Desktop 或 SQL 创建的各个要素类。
除了指定坐标系之外,您还必须创建一个空间参考。ArcGIS Desktop 将其视为要素类创建过程的一部分来完成。要使用 SQL 为表创建空间参考,请参阅为包含 ST_Geometry 列的表创建空间索引。
PostgreSQL 文档所在位置
您可以登录 PostgreSQL 网站获得 PostgreSQL 文档,网址为 http://www.postgresql.org/docs/。此文档中包含有关 PostgreSQL 的安装和管理、SQL 命令和编程方面的信息以及使用 PostgreSQL 的教程。
- 用户组
在世界范围内存在众多 PostgreSQL 用户组。要获得包含某些用户组的列表,可登录网站 http://pugs.postgresql.org/。
- 案例研究
要获得使用 PostgreSQL 的案例研究站点的链接,可登录网站 http://www.postgresql.org/about/casestudies/。
- 每周新闻
下方网站每周都会发布社区时事简讯并在其中详细叙述与 PostgreSQL 相关的新发展和信息:http://www.postgresql.org/community/weeklynews/。