定义
ST_Transform 将二维 ST_Geometry 数据作为输入,并返回已转换为空间参考的值,该空间参考由您所提供的空间参考 ID (SRID) 指定。
如果地理坐标系不同,则 ST_Transform 将执行地理变换。地理变换是指在两个地理坐标系间进行转换。地理变换定义为在特定转换方向上进行,例如,从 NAD 1927 到 NAD 1983,但不管源和目标坐标系是什么,ST_Transform 函数都能正确执行变换。
地理转换方法可以分为两类:基于方程和基于文件。基于方程的方法是独立的,不需要任何外部信息。基于文件的方法使用磁盘上的文件计算偏移值。与基于方程的方法相比,基于文件的方法通常更加精确。在澳大利亚、加拿大、德国、新西兰、西班牙和美国,一般使用基于文件的方法。文件(加拿大除外)可从 ArcGIS Desktop 安装获得或直接从各种国家制图机构获得。
要支持基于文件的变换,必须将文件置于数据库服务器中与 ArcGIS Desktop安装目录中的 pedata 文件夹相同的相对文件夹结构中。
例如,名为 pedata 的文件夹位于 ArcMap 安装目录和 ArcGIS Pro 安装目录的 Resources 文件夹中。pedata 文件夹包含多个子文件夹,但三个包含受支持基于文件的方法的文件夹分别为:harn、nadcon 和 ntv2。可以将 pedata 文件夹及其内容从 ArcGIS 安装目录复制到数据库服务器,或在数据库服务器上创建一个目录,其中包含受支持基于文件的变换方法子目录及文件。文件复制到数据库服务器之后,可在同一服务器上设置名为 PEDATAHOME 的操作系统环境变量。将 PEDATAHOME 变量设置为包含子目录和文件的目录位置;例如,如果在 Microsoft Windows 服务器中将 pedata 文件夹复制到 C:\pedata 下,则将 PEDATAHOME 环境变量设置为 C:\pedata。
有关如何设置环境变量的信息,请参阅操作系统文档。
设置 PEDATAHOME 后,必须先启动新的 SQL 会话,才能使用 ST_Transform 函数;但无需重新启动服务器。
在 PostgreSQL 中使用 ST_Transform
在 PostgreSQL 中,可以在具有相同地理坐标系或不同地理坐标系的空间参考之间进行转换。
如果数据存储在数据库(而非地理数据库)中,请在地理坐标系相同的情况下,执行以下操作更改 ST_Geometry 数据的空间参考:
- 创建表的备份副本。
- 在表中创建第二个(目标)ST_Geometry 列。
- 注册目标 ST_Geometry 列,并指定新的 SRID。
此操作通过在 sde_geometry_columns 系统表中放置记录来指定列的空间参考。
- 执行 ST_Transform。指定变换所得数据应输出到目标 ST_Geometry 列。
- 取消注册第一个(源)ST_Geometry 列。
如果数据存储在地理数据库中,应使用 ArcGIS 工具将数据重新投影到新要素类。在地理数据库要素类中执行 ST_Transform 将忽略使用新 SRID 更新地理数据库系统表的功能。
在 Oracle 中使用 ST_Transform
在 Oracle 中,可以在具有相同地理坐标系或不同地理坐标系的空间参考之间进行转换。
如果数据存储在数据库(而非地理数据库)中且在空间列中未定义空间索引,则可以添加第二个 ST_Geometry 列并将变换所得数据输出到此列中。尽管使用视图或更改表的查询图层定义每次只能在 ArcGIS 中显示一列,但仍可以在表中同时保留原始(源)ST_Geometry 列和目标 ST_Geometry 列。
如果数据存储在数据库(而非地理数据库)中,并且存在在空间列中定义的空间索引,则无法保留原始 ST_Geometry 列。在 ST_Geometry 列中定义空间索引后,SRID 将写入 st_geometry_columns 元数据表中。ST_Transform 将不更新该表。
- 创建表的备份副本。
- 在表中创建第二个(目标)ST_Geometry 列。
- 执行 ST_Transform。指定变换所得数据应输出到目标 ST_Geometry 列。
- 从源 ST_Geometry 列删除空间索引。
- 删除源 ST_Geometry 列。
- 在目标 ST_Geometry 列创建空间索引。
如果数据存储在地理数据库中,应使用 ArcGIS 工具将数据重新投影到新要素类。在地理数据库要素类中执行 ST_Transform 将忽略使用新 SRID 更新地理数据库系统表的功能。
在 SQLite 中使用 ST_Transform
在 SQLite 中,可以在具有相同地理坐标系或不同地理坐标系的空间参考之间进行转换。
语法
源和目标空间参考具有相同的地理坐标系
Oracle 和 PostgreSQL
sde.st_transform (geometry1 sde.st_geometry, srid integer)
SQLite
st_transform (geometry1 geometryblob, srid in32)
源和目标空间参考具有不同的地理坐标系
Oracle
sde.st_transform (g1 sde.st_geometry, srid integer, geogtrans_id integer)
PostgreSQL
选项 1:sde.st_transform (g1 sde.st_geometry, srid int)
选项 2:sde.st_transform (g1 sde.st_geometry, srid int, [geogtrans_id int])
选项 3:sde.st_transform (g1 sde.st_geometry, srid int, [extent double] [prime meridian double] [unit conversion factor double])
在选项 3 中,可以选择性地按照以下顺序指定范围,即以逗号分隔的坐标列表:左下 x 坐标、左下 y 坐标、右上 x 坐标、右上 y 坐标。如果未指定范围,则 ST_Transform 将使用更大更常用的范围。
指定范围时,本初子午线和单位转换因子参数为可选项。仅当您指定的范围值未使用格林尼治本初子午线或十进制度时,才需要提供此信息。
有关其他预定义本初子午线的列表,请参阅 http://www.epsg-registry.org。
SQLite
st_transform (geometry1 geometryblob, srid int32, geogtrans_id int32)
返回类型
Oracle 和 PostgreSQL
ST_Geometry
SQLite
Geometryblob
示例
源和目标空间参考具有相同的地理坐标系时转换数据
下例中,将创建包含以下两个线串列的表 transform_test:ln1 和 ln2。向 ln1 插入线,SRID 为 4326。然后在 UPDATE 语句中使用 ST_Transform 函数获取 ln1 中的线串,将线串由分配给 SRID 4326 的坐标参考转换为分配给 SRID 3857 的坐标参考,再将其置于 ln2 列中。
Oracle
CREATE TABLE transform_test (
ln1 sde.st_geometry,
ln2 sde.st_geometry);
INSERT INTO transform_test (ln1) VALUES (
sde.st_geometry ('linestring (10.01 40.03, 92.32 29.39)', 4326)
);
UPDATE transform_test
SET ln2 = sde.st_transform (ln1, 3857);
PostgreSQL
CREATE TABLE transform_test (
ln1 sde.st_geometry,
ln2 sde.st_geometry);
INSERT INTO transform_test (ln1) VALUES (
sde.st_geometry ('linestring (10.01 40.03, 92.32 29.39)', 4326)
);
UPDATE transform_test
SET ln2 = sde.st_transform (ln1, 3857);
SQLite
CREATE TABLE transform_test (id integer);
SELECT AddGeometryColumn(
NULL,
'transform_test',
'ln1',
4326,
'linestring',
'xy',
'null'
);
INSERT INTO transform_test (ln1) VALUES (
st_geometry ('linestring (10.01 40.03, 92.32 29.39)', 4326)
);
UPDATE transform_test
SET ln1 = st_transform (ln1, 3857);
源和目标空间参考不具有相同的地理坐标系时转换数据
下例中,将创建包含 ID 列和几何列的表 n27。向表 n27 中插入点,SRID 为 4267。4267 SRID 使用 NAD 1927 地理坐标系。
然后创建表 n83 并使用 ST_Transform 函数将表 n27 中的几何插入到表 n83 中,但 SRID 为 4269,地理变换 ID 为 1241。SRID 4269 使用 NAD 1983 地理坐标系,1241 为 NAD_1927_To_NAD_1983_NADCON 变换的熟知 ID。此变换是基于文件的变换并且可用于美国本土的 48 个州。
Oracle
--Create table.
CREATE TABLE n27 (
id integer,
geometry sde.st_geometry
);
--Insert point with SRID 4267.
INSERT INTO N27 (id, geometry) VALUES (
1,
sde.st_geometry ('point (-123.0 49.0)', 4267)
);
--Create the n83 table as the destination table of the transformation.
CREATE TABLE n83 (
id integer,
geometry sde.st_geometry
);
--Run the transformation.
INSERT INTO N83 (id, geometry)(
select c.id, sde.st_transform (c.geometry, 4269, 1241)
from N27 c
);
如果 PEDATAHOME 正确定义,则针对 n83 表格的 SELECT 语句运行将返回以下内容:
SELECT id, sde.st_astext (geometry) description
FROM N83;
ID DESCRIPTION
1 | POINT((-123.00130569 48.999828199))
PostgreSQL
--Option 1
--Gets geographic transformation from ST_Geometry libraries.
--Does not require you to provide a GTid.
--Performs an equation-based transformation between two geographic coordinate systems
--with different datums. (SRID 4267/DATUM NAD27 to SRID 4269/DATUM NAD 83)
--Provide point to transform.
SELECT sde.ST_AsText(sde.ST_Transform(
sde.ST_Geometry('point (-155.7029 63.6096)',4267), 4269));
--Returns output in SRID 4269.
"POINT ( -155.70290000 63.60960000)"
--Option 2
--Example uses input point in SRID 3857(DATUM: WGS 1984)
--and geographic transformation ID (GTid) 1251.
--Transforms point to SRID 102008 (DATUM: NAD 83)
--Provide point to transform.
SELECT sde.ST_AsText(sde.ST_Transform(
sde.ST_Geometry('point (-13244252.9404 4224702.5198)', 3857), 102008, 1251));
--Returns output in SRID 102008.
"POINT (-1957193.14740000 -297059.19680000)"
SQLite
--Create source table.
CREATE TABLE n27 (id integer);
SELECT AddGeometryColumn(
NULL,
'n27',
'geometry',
4267,
'point',
'xy',
'null'
);
--Insert point with SRID 4267.
INSERT INTO n27 (id, geometry) VALUES (
1,
st_geometry ('point (-123.0 49.0)', 4267)
);
--Create the n83 table as the destination table of the transformation.
CREATE TABLE n83 (id integer);
SELECT AddGeometryColumn(
NULL,
'n83',
'geometry',
4269,
'point',
'xy',
'null'
);
--Run the transformation.
INSERT INTO n83 (id, geometry) VALUES (
1,
st_transform ((select geometry from n27 where id=1), 4269, 1241)
);