PostgreSQL 中的 ST_Geometry

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

PostgreSQL 中的地理数据库默认使用 ST_Geometry 空间类型,但是您必须在创建地理数据库之前将 st_geometry 库复制到 PostgreSQL 安装程序。有关说明,请参阅在 Windows 上的 PostgreSQL 中创建地理数据库在 Linux 上的 PostgreSQL 中创建地理数据库。如果使用不包含地理数据库的 PostgreSQL 数据库,您可以安装 ST_Geometry 类型,以便在数据库中创建的空间表中使用。

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

ST_Geometry 如何存储空间数据

以下是有关 PostgreSQL 中 ST_Geometry 的描述:

姓名Type说明

大小

LONG INTEGER

ST_Geometry 结构的总长度(包括形状缓冲区)

srid

LONG INTEGER

包含几何的标识符,用于将几何链接到与之关联的 sde_spatial_references 表中的空间参考(坐标系)记录

numpts

LONG INTEGER

定义几何的点数;对于多部分几何,还包括各个部分之间的分隔符,每个分隔符对应一个点

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

最大测量值

面积

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_Length 返回几何体的长度。
  • 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 的构造函数定义是相同的。构造函数名与其构造的类型名相同。

ST_Geometry 方案定义

PostgreSQL 函数的空间类型、表和视图均存储在 sde 方案中。方案定义是用于定义和描述列/表类型、空间索引和空间参考信息的系统表的基表描述。

表为 sde_geometry_columns 和 sde_coordinate_systems。基于这些表的视图为 st_geometry_columns 和 st_spatial_references。

抢先版本:

除系统表、视图和函数外,以下数据库对象也用于维护 ST_Geometry 信息:

  • sde 登录角色
  • 数据库中的 sde 方案
  • ST_Geometry 触发器:sde_coord_sys_def_insert_tg
  • ST_Geometry 域:
    • st_geomcollection
    • st_linestring
    • st_multilinestring
    • st_multipoint
    • st_multipolygon
    • st_point
    • st_polygon

使用 ArcGIS 创建采用 ST_Geometry 存储的要素类

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

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

在数据库中

指定在 ArcGIS 中创建要素类时要使用的空间数据类型。

在地理数据库中

要素类存储信息由 sde_dbtune 表中的配置关键字设置控制。在 ArcGIS 中创建要素类时指定配置关键字。创建地理数据库时,DEFAULTS 配置关键字会将 GEOMETRY_STORAGE 参数设置为 ST_Geometry。如果想要使用 ST_Geometry 类型存储所有或大部分空间数据,请不要更改 DEFAULTS 关键字的 GEOMETRY_COLUMNS 参数值,通过 ArcGIS 创建要素类时,再指定 DEFAULTS 关键字。

如果您更改 DEFAULTS GEOMETRY_STORAGE 参数以使用 PostGIS 几何或地理数据类型,但想要使用 ST_Geometry 数据类型创建一些要素类,可以为 ST_Geometry 存储创建新的配置关键字。使用导出地理数据库配置关键字地理处理工具将 sde_dbtune 表中的内容导出到文本文件中,添加一个关键字,将 GEOMETRY_STORAGE 设置为 ST_GEOMETRY,然后使用导入地理数据库配置关键字地理处理工具导入所做的更改。例如,您可以导出 sde_dbtune 表并添加一个配置关键字,如下所示:

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

添加关键字后,在 ArcGIS 中创建要素类时可指定此关键字,这样新的要素类将使用 ST_Geometry 存储。

使用 ArcGIS 访问包含 ST_Geometry 列的 PostgreSQL 表

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

  • 该表必须具有单个 ST_Geometry 列。
  • 该表必须没有属于用户定义类型的其他列。
  • 如果该表存储多种几何类型(点、线和面),则必须指定要查看的几何类型;ArcGIS 每次只能查看一种类型。
  • 表中所有记录必须使用相同的空间参考。

如果在地理数据库中使用 SQL 创建了表,则想要使用地理数据库功能(例如复制、网络、关系类和拓扑),或想要在 ArcGIS 中编辑表时,您可以将表注册到地理数据库。 要将表注册到地理数据库,必须满足以下条件:

  • 表必须归注册此表的用户所有。
  • 必须具有单个 ST_Geometry 列。
  • 必须没有属于用户定义类型的其他列。
  • 几何的类型必须单一(点、线或面)。
  • 表中所有记录必须使用相同的空间参考。
  • 还必须具有可用作 ObjectID 的唯一非空整型列。

注册 ST_Geometry 列

如果使用 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 并仅存储三维坐标:

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