16. 投影数据

地球不是平坦的,也没有简单的方法可以将其绘制在平坦的纸质地图(或计算机屏幕)上,因此人们想出了各种巧妙的解决方案,每种方案都有利有弊。有些投影保留面积,因此所有对象都具有彼此的相对大小;其他投影保留角度(等角),如墨卡托投影;一些投影试图找到在几个参数上只有很小失真的良好中间混合。所有投影的共同点是它们将(球形)世界转换到平面笛卡尔坐标系上,选择哪种投影取决于您将如何使用数据。

当我们 加载 nyc 数据 <loading_data>`时,我们已经遇到了投影。 (回想一下那个讨厌的 SRID 26918)。然而,有时您需要在空间参考系统之间进行转换和重新投影。 PostGIS 包含使用 :command:`ST_Transform(geometry, srid) 函数更改数据投影的内置支持。为了管理几何上的空间参考标识符,PostGIS 提供了 ST_SRID(geometry) 和:command:`ST_SetSRID(geometry, srid)`函数。

我们可以使用 :command:`ST_SRID`函数确认数据的 SRID :

SELECT ST_SRID(geom) FROM nyc_streets LIMIT 1;
26918

“26918”的定义是什么?正如我们在“加载空间数据 <loading_data>”中看到的,定义包含在``spatial_ref_sys``表中。事实上,有**两个**定义。 “众所周知的文本”(WKT) 定义位于 ``srtext` 列中, ``proj4text``列中还有“proj.4”格式的第二个定义。

SELECT * FROM spatial_ref_sys WHERE srid = 26918;

PostGIS 重投影引擎将尝试从``spatial_ref_sys``表中找到最佳投影:

  • auth_name / auth_srid 如果 proj 可以在其内部目录中找到有效的“权限名称”和“权限 srid”,它将使用它来生成投影定义。

  • srtext 如果 proj 可以从 srtext 解析并形成定义对象,它将使用它。

  • proj4text 最后,proj 将尝试处理 proj4text

所有这些冗余意味着在 PostGIS 中创建新投影所需的只是有效的 srtext 字符串或 ``proj4text``字符串。默认情况下,所有常见权限名称/代码对均已加载到表中。

如果您在创建自定义投影时可以选择,请填写``srtext``列,因为该列也由 GeoServer, QGIS,和 `FME <http://www.safe.com/>`等外部程序使用。

16.1. 比较数据

坐标和 SRID 一起定义地球上的位置。如果没有 SRID,坐标只是一个抽象概念。 “笛卡尔”坐标平面被定义为放置在地球表面上的“平面”坐标系。由于 PostGIS 函数在这样的平面上工作,因此比较操作要求两个几何图形在同一 SRID 中表示。

如果您输入具有不同 SRID 的几何图形,您只会收到错误消息:

SELECT ST_Equals(
         ST_GeomFromText('POINT(0 0)', 4326),
         ST_GeomFromText('POINT(0 0)', 26918)
         );
ERROR:  ST_Equals: Operation on mixed SRID geometries (Point, 4326) != (Point, 26918)

注解

小心不要过于高兴地使用:command:ST_Transform 进行即时转换。空间索引是使用存储的几何图形的 SRID 构建的。如果在不同的 SRID 中进行比较,则(通常)不使用空间索引。最佳实践是为数据库中的所有表选择**一个 SRID**。仅当您向外部应用程序读取或写入数据时才使用转换函数。

16.2. 转换数据

如果我们返回到 SRID 26918 的 proj4 定义,我们可以看到我们的工作投影是 18 区的 UTM(通用横轴墨卡托),以米为测量单位。

SELECT srtext FROM spatial_ref_sys WHERE srid = 26918;
PROJCS["NAD83 / UTM zone 18N",
  GEOGCS["NAD83",
    DATUM["North_American_Datum_1983",
      SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],
      TOWGS84[0,0,0,0,0,0,0],
      AUTHORITY["EPSG","6269"]],
    PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],
    UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],
    AUTHORITY["EPSG","4269"]],
  PROJECTION["Transverse_Mercator"],
  PARAMETER["latitude_of_origin",0],
  PARAMETER["central_meridian",-75],
  PARAMETER["scale_factor",0.9996],
  PARAMETER["false_easting",500000],
  PARAMETER["false_northing",0],
  UNIT["metre",1,AUTHORITY["EPSG","9001"]],
  AXIS["Easting",EAST],AXIS["Northing",NORTH],
  AUTHORITY["EPSG","26918"]]

让我们将工作投影中的一些数据转换为地理坐标——也称为“经度/纬度”。

要将数据从一种 SRID 转换为另一种,您必须首先验证您的几何图形是否具有有效的 SRID。由于我们已经确认了有效的 SRID,接下来我们需要将投影转换为 SRID。换句话说,地理坐标的SRID是多少?

地理坐标最常见的 SRID 是 4326,对应于“WGS84 椭球体上的经度/纬度”。您可以在这里查看定义:

您还可以从 ``spatial_ref_sys``表中提取定义:

SELECT srtext FROM spatial_ref_sys WHERE srid = 4326;
GEOGCS["WGS 84",
  DATUM["WGS_1984",
    SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],
    AUTHORITY["EPSG","6326"]],
  PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],
  UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],
  AUTHORITY["EPSG","4326"]]

让我们将“Broad St”地铁站的坐标转换为地理坐标:

SELECT ST_AsText(ST_Transform(geom,4326))
FROM nyc_subway_stations
WHERE name = 'Broad St';
POINT(-74.01067146887341 40.70710481558761)

如果您在未指定 SRID 的情况下加载数据或创建新几何图形,则 SRID 值将为 0。回想一下几何:ref:geometries,当我们创建``geometries``表时,我们没有指定 SRID。如果我们查询数据库,我们应该期望所有``nyc_``表的 SRID 为 26918,而g``geometries`` 表的默认 SRID 为 0。

要查看表的 SRID 分配,请查询数据库的 geometry_columns 表。

SELECT f_table_name AS name, srid
FROM geometry_columns;
        name         | srid
---------------------+-------
 nyc_census_blocks   | 26918
 nyc_homicides       | 26918
 nyc_neighborhoods   | 26918
 nyc_streets         | 26918
 nyc_subway_stations | 26918
 geometries          |     0

但是,如果您知道坐标的 SRID 应该是什么,则可以在几何体上使用 :command:`ST_SetSRID`事后设置它。然后您将能够将几何图形转换为其他系统。

SELECT ST_AsText(
    ST_Transform(
      ST_SetSRID(geom,26918),
      4326)
    )
  FROM geometries;

16.3. 函数列表

ST_AsText: 返回几何/地理对象的不带SRID元数据的Well-Known Text(WKT)表示。

ST_SetSRID(geometry, srid): 将几何体上的 SRID 设置为特定整数值。

ST_SRID(geometry): 返回 Spatial_ref_sys 表中定义的 ST_Geometry 的空间参考标识符。

ST_Transform(geometry, srid):返回一个新的几何图形,其坐标转换为整数参数引用的 SRID。