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 中的地理数据库内创建的数据。

本主题将介绍如下内容

要了解如何使用 SQL 对采用 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 作为输入并以数字形式返回请求的属性值。

例如,以下查询可返回美国各个州的名称和面积。

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 所需满足的条件如下所示:

表中还必须包含一个可用作行 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>)
    要注册 blocks 表的 shape 列并为该表分配一个 SRID,请执行以下语句:
    SELECT st_register_spatial_column(
    'mycitydb', 'sasha', 'blocks', 'shape', 4)
    这样即可在地理数据库中向 sde_geometry_columns 表添加空间列。您所指定的 SRID(在上例中为 4)必须存在于 sde_spatial_references 表中。如果 sde_spatial_references 表中没有所需空间参考,则可打开 ArcCatalog,连接到地理数据库,然后创建一个使用所需空间参考系和 ST_Geometry 存储的新要素类。执行上述操作后,系统会用所需空间参考填充 sde_spatial_references 表,然后 ArcCatalog 将为您计算出 x,y、z 和 m 偏移值、单位和图层范围。您也可以使用 SQL 插入空间参考,但必须确保自行计算出的 x,y、z 和 m 偏移值和单位准确无误。但请注意,要使用 sdelayer 命令将表注册到 ArcSDE,必须取消注册 ST_Geometry 列。例如,假如您创建一张表,其他用户将使用 SQL 对该表执行插入操作。要强制使用单一 SRID,可以将 ST_Geometry 列注册为所需的 SRID。然后,当您决定将该表注册到 ArcSDE 时,可执行 st_unregister_spatial_column 功能。(参见下一条提示。)
  • 要取消注册某个空间列,您可以执行 st_unregister_spatial_column() 功能。此功能取消注册空间列的方法是,将某个空间列从 sde_geometry_columns 系统表中移除,这样该空间列便不再与任何空间参考系统关联。
    SELECT st_unregister_spatial_column(
    '<database_name>', '<schema_name>',
     '<table_name>', '<column_name>')
    将表注册到 ArcSDE 之前或者要将空的空间列注册为其他 SRID 时,您可能需要执行该操作;可以先取消注册,然后通过 st_register_spatial_column 命令将其注册为其他 SRID。
  • 您可以通过执行 st_isregistered_spatial_column 功能来检查某个空间列是否已经注册。
    SELECT st_isregistered_spatial_column(
    '<database_name>', '<schema_name>',
     '<table_name>', '<column_name>', <srid>) 
    如果该空间列已注册,将返回值 1,而如果该空间列未注册,则将返回值 0。

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 的教程。


3/7/2012