PostgreSQL 中的 ST_Geometry 存储

PostgreSQL 中可以使用两种不同的空间存储类型:ST_Geometry 和 PostGIS geometry。借助这些数据类型,可以将空间数据同其他类型的商业数据进行集成,从而使多用户数据库通过将地理组件添加到分析和数据产品而从中受益。将空间数据与其他业务对象一起存储还可简化数据的多用户访问、管理并增强安全性,因为这样做减少了要管理的数据存储资源。

默认情况下,PostgreSQL 中的地理数据库使用 ST_Geometry 空间类型。还可以在 PostgreSQL 数据库中安装 ST_Geometry 类型。有关在 PostgreSQL 数据库中安装 ST_Geometry 类型的信息,请参阅将 ST_Geometry 类型添加到 PostgreSQL 数据库

为了帮助您了解如何在 PostgreSQL 中使用 ST_Geometry 类型,本主题将介绍

要了解如何使用 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

存储在空间列中的几何要素的类型(线串、多线串、多点、多面、点和面)

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 存储创建要素类

选择通过 ArcGIS for Desktop 创建要素类时要使用的存储类型。

在使用 ST_Geometry 存储的 ArcGIS 中创建要素类时,该要素类的业务表将带有一个 ST_Geometry 类型列,并且要素类的空间数据将存储在该列中。

在连接到数据库时,如果 ST_Geometry 类型是您要使用的空间列类型,则在创建空间表时选择 ST_Geometry。有关在数据库中创建表的信息,请参阅在 ArcGIS 中创建空间数据库表

如果连接到地理数据库,则通过选择要使用的配置关键字指定存储方式。默认存储设置是通过 DEFAULTS 配置关键字的 GEOMETRY_STORAGE 参数在 sde_dbtune 表中进行定义的。如果您未更改 DEFAULTS 关键字的 GEOMETRY_STORAGE 参数值,除非在创建要素类时指定其他配置关键字,否则所有要素类均会使用 ST_Geometry 存储来创建。

如果更改 DEFAULTS GEOMETRY_STORAGE 参数以使用 PostGIS 几何,则仍然可以创建使用 ST_Geometry 存储的要素类。为此,在 sde_dbtune 表中创建 ST_Geometry 存储的新配置关键字。例如,可以按如下方式创建配置关键字:

##ST_GEOMETRY
GEOMETRY_STORAGE    "ST_GEOMETRY"
UI_TEXT   "User-interface for ST_GEOMETRY keyword"

END

随后,当在 ArcGIS 中创建要素类时选择该关键字,新要素类即会使用 ST_Geometry 存储。

提示提示:

使用 sdedbtune 命令将值更改或添加到 sde_dbtune 表。有关说明,请参阅修改 DBTUNE 表的内容

访问具有 ST_Geometry 列的 PostgreSQL 表

如果使用 SQL 创建具有 ST_Geometry 列的表,则可以通过 SQL 或自定义第三方应用程序访问数据,并且可以访问 ArcGIS 中的表。当从 ArcGIS 连接到数据库时,可以查看、执行分析,或者将数据加载到包含 ST_Geometry 列的表中。为此,必须满足以下条件:

如果使用 SQL 在地理数据库中创建表,可以使用地理数据库注册该表;如果要使用地理数据库功能(例如复制、网络、关系类和拓扑)或者要在 ArcGIS 中编辑表,可以使用地理数据库注册表,前提条件是满足以下条件:

注册空间列

如果使用 SQL 创建包含 ST_Geometry 列的表,可注册该列以使用特定的空间参考和维数。这样,通过 SQL 插入记录的用户便不会意外插入使用不同空间参考或包含不同维数的记录。要执行此操作,请使用 sde.st_register_spatial_column 函数。使用此函数的语法如下:

SELECT st_register_spatial_column('<database_name>', '<schema_name>', 
'<table_name>', '<spatial_column_name>', <srid>, <coordinate_dimension>)

public.sde_spatial_references 表中必须存在您指定的 SRID。坐标维度表示数据仅有 x,y 坐标 (2) 还是有 x,y,z 坐标 (3)、x,y,z,m 坐标 (4) 或 x,y,m 坐标 (5)。默认情况下,如果不指定坐标维度,则数据将注册为仅有 x,y 维度。

在以下示例中,注册数据库 mycitydb 的 sasha 方案中块表的 shape 列,以便使用 4236 的 SRID 并仅存储 3 维坐标:

SELECT st_register_spatial_column(
'mycitydb', 'sasha', 'blocks', 'shape', 4236, 3);

这样即可在地理数据库或数据库中向 public.sde_geometry_columns 表添加空间列的记录。

如果空间列为空并且使用特定 SRID 和维数注册该空间列,则可以取消注册以更改 SRID 或维数,然后使用其他值重新注册该空间列。要取消注册某个空间列,您可以执行 st_unregister_spatial_column() 函数。此函数用于从 public.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>)

如果已经使用指定 SRID 注册该空间列,则返回 1;如果没有注册,则返回 0。

要查询注册表所使用的维数,可使用 st_get_coord_dimension 函数。st_get_coord_dimension 函数的语法如下:

SELECT st_get_coord_dimension(
'<schema_name>', '<table_name>', '<column_name>', <srid>)

在此示例中,st_get_coord_dimension 将返回 xyz,因为该块表已注册为三维:

SELECT st_get_coord_dimension(
'sasha', 'blocks', 'shape', 4236);

st_get_coord_dimension
---------------------------
xyz
9/15/2013