地球不是平坦的,没有简单的方法可以将其放在平面的纸质地图(或计算机屏幕)上,因此人们想出了各种巧妙的解决方案,每种解决方案各有利弊。有些投影会保留区域,因此所有对象之间的大小都相对。其他投影像墨卡托投影一样保留角度(共形);一些预测试图找到一个好的中间混合,在几个参数上只有很小的失真。所有投影的共同点是它们将(球形)世界转换为平坦的笛卡尔坐标系,选择哪种投影取决于如何使用数据。
加载nyc数据时,我们已经遇到了投影。 (回想一下令人讨厌的SRID 26918)。但是,有时需要在空间参照系之间进行转换和重新投影。 PostGIS包含使用ST_Transform(geometry,srid)
函数更改数据投影的内置支持。为了管理几何上的空间参考标识符,PostGIS提供了ST_SRID(geometry)
和ST_SetSRID(geometry,srid)
函数。
我们可以使用ST_SRID()
函数来确认数据的SRID:
SELECT ST_SRID(geom) FROM nyc_streets LIMIT 1;
----------------------------------
26918
“ 26918”的定义是什么? 该定义包含在spatial_ref_sys表中。 实际上,有两个定义。 srtext列中有“知名文本”(WKT)定义,proj4text列中还有“ proj.4”格式的第二个定义。
SELECT * FROM spatial_ref_sys WHERE srid = 26918;
实际上,对于内部PostGIS重新投影计算,使用的是proj4text列的内容。 对于我们的26918投影,这是proj.4文本:
SELECT proj4text FROM spatial_ref_sys WHERE srid = 26918;
+proj=utm +zone=18 +ellps=GRS80 +datum=NAD83 +units=m +no_defs
实际上,srtext和proj4text列都很重要:srtext列由GeoServer,QGIS和FME等外部程序使用; proj4text列在内部使用。
比较数据
总而言之,坐标和SRID定义了地球上的位置。 没有SRID,坐标只是一个抽象概念。 “笛卡尔”坐标平面定义为放置在地球表面的“平面”坐标系。 由于PostGIS功能在这样的平面上工作,因此比较操作要求两个几何都用同一SRID表示。
如果输入具有不同SRID的几何图形,则只会出现错误:
SELECT ST_Equals(
ST_GeomFromText('POINT(0 0)', 4326),
ST_GeomFromText('POINT(0 0)', 26918)
);
----------------------------------------
ERROR: Operation on two geometries with different SRIDs
CONTEXT: SQL function "st_equals" statement 1
注意
请谨慎使用ST_Transform进行即时转换,以免感到满意。 使用存储的几何的SRID构建空间索引。 如果比较是在不同的SRID中完成的,则(通常)不使用空间索引。 最佳实践是为数据库中的所有表选择一个SRID。 仅在将数据读取或写入外部应用程序时使用转换功能。
转换数据
如果返回到SRID 26918的proj4定义,可以看到我们的工作投影是18区的UTM(通用横轴墨卡托),以米为测量单位。
+proj=utm +zone=18 +ellps=GRS80 +datum=NAD83 +units=m +no_defs
让我们将一些数据从工作投影转换为地理坐标-也称为“经度/纬度”。
要将数据从一个SRID转换为另一个SRID,必须首先验证几何图形具有有效的SRID。 由于我们已经确认了有效的SRID,因此接下来需要将投影的SRID转换为。 换句话说,什么是地理座标的SRID?
地理坐标最常见的SRID是4326,它对应于“ WGS84椭球体上的经度/纬度”。 可以在<spatialreference.org>网站上看到该定义:
还可以从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.0106714688735 40.7071048155841)
如果加载数据或创建新几何而不指定SRID,则SRID值为0。
SELECT ST_SRID('POINT(1 1)'::geometry);
----------------------------------------
0
如果知道坐标的SRID应该是什么,则可以使用几何图形上的ST_SetSRID在事后设置它。 然后,能够将几何转换为其他系统。
SELECT ST_SRID(ST_SetSRID('POINT(1 1)'::geometry, 4326));
4326