20. 几何构造函数¶
到目前为止,我们看到的所有函数都使用“原样”的几何体,并返回
对象的分析 (ST_Length(geometry), ST_Area(geometry)),
对象的序列化 (ST_AsText(geometry), ST_AsGML(geometry)),
对象的各个部分 (ST_RingN(geometry,n)) 或
真/假测试 (ST_Contains(geometry,geometry), ST_Intersects(geometry,geometry)).
“几何构造函数”将几何体作为输入,并输出新的形状。
20.1. ST_Centroid / ST_PointOnSurface¶
在构建空间查询时,一个常见的需求是用要素的点表示来替换多边形要素。这对于空间连接(如 多边形/多边形连接 中所述)非常有用,因为在两个多边形图层上使用 ST_Intersects(geometry,geometry) 通常会导致重复计数:边界上的多边形将与两侧的对象相交;用点替换它会迫使它位于一边或另一边,而不是两边。
ST_Centroid(geometry) 返回一个点,该点大约位于输入参数的质量中心。这种简单的计算非常快,但有时不可取,因为返回的点不一定在要素本身内。如果输入要素具有凸度(想象字母“C”),则返回的质心可能不在要素的内部。
ST_PointOnSurface(geometry) 返回一个点,该点保证在输入参数内。这使得它更适合于计算空间连接的“代理点”。
-- Compare the location of centroid and point-on-surface for a concave geometry
SELECT ST_Intersects(geom, ST_Centroid(geom)) AS centroid_inside,
ST_Intersects(geom, ST_PointOnSurface(geom)) AS pos_inside
FROM (VALUES
('POLYGON ((30 0, 30 10, 10 10, 10 40, 30 40, 30 50, 0 50, 0 0, 0 0, 30 0))'::geometry)
) AS t(geom);
centroid_inside | pos_inside
-----------------+------------
f | t
20.2. ST_Buffer¶
缓冲操作在 GIS 工作流程中很常见,PostGIS 中也提供了该操作。 ST_Buffer(geometry,distance) 接收缓冲距离和几何类型,并输出一个多边形,其边界距离输入几何的缓冲距离。
例如,如果美国国家公园管理局想要在自由岛周围设立一个海上交通管制区,他们可能会在该岛周围建立一个 500 米的缓冲多边形。自由岛是我们 nyc_census_blocks
表中的一个普查区,因此我们可以轻松地提取并缓冲它。
-- Make a new table with a Liberty Island 500m buffer zone
CREATE TABLE liberty_island_zone AS
SELECT ST_Buffer(geom,500)::geometry(Polygon,26918) AS geom
FROM nyc_census_blocks
WHERE blkid = '360610001001001';
ST_Buffer 函数也接受负距离,并在多边形输入内构建内接多边形。对于线和点,您将只获得一个空返回值。
20.3. ST_Intersection¶
另一个经典的 GIS 操作——“叠加”——通过计算两个叠加多边形的交集来创建一个新的覆盖范围。结果具有以下属性:父级中的任何多边形都可以通过合并结果中的多边形来构建。
ST_Intersection(geometry A, geometry B) 函数返回两个参数共有的空间区域(或线,或点)。如果参数是不相交的,则该函数返回一个空几何。
-- What is the area these two circles have in common?
-- Using ST_Buffer to make the circles!
SELECT ST_AsText(ST_Intersection(
ST_Buffer('POINT(0 0)', 2),
ST_Buffer('POINT(3 0)', 2)
));
20.4. ST_Union¶
在前面的示例中,我们对几何进行了交集运算,创建了一个新的几何,该几何包含来自两个输入的线。 ST_Union 函数执行相反的操作;它接收输入并删除公共线。 ST_Union 函数有两种形式
ST_Union(geometry, geometry):一个双参数版本,接收两个几何并返回合并的并集。例如,我们上一节中的两个圆形示例,当您用并集替换交集时,看起来像这样。
-- What is the total area these two circles cover? -- Using ST_Buffer to make the circles! SELECT ST_AsText(ST_Union( ST_Buffer('POINT(0 0)', 2), ST_Buffer('POINT(3 0)', 2) ));
ST_Union([geometry]):一个聚合版本,接收一组几何,并返回整个组的合并几何。聚合 ST_Union 可以与
GROUP BY
SQL 语句一起使用,以创建精心合并的基本几何子集。它非常强大。
以 ST_Union 聚合为例,考虑我们的 nyc_census_blocks
表格。人口普查地理信息经过精心构建,以便可以从较小的地理信息构建更大的地理信息。因此,我们可以通过合并构成每个区段的街区来创建人口普查区段地图(正如我们在后面的 创建人口普查区段表格 中所做的那样)。或者,我们可以通过合并每个县内的街区来创建县地图。
为了进行合并,请注意唯一键 blkid
实际上包含了关于更高层级地理信息的信息。以下是我们之前使用的自由岛键的各个部分
360610001001001 = 36 061 000100 1 001
36 = State of New York
061 = New York County (Manhattan)
000100 = Census Tract
1 = Census Block Group
001 = Census Block
因此,我们可以通过合并所有 blkid
的前 5 位数字相同的几何图形来创建县地图。请耐心等待;这在计算上非常昂贵,可能需要一两分钟。
-- Create a nyc_census_counties table by merging census blocks
CREATE TABLE nyc_census_counties AS
SELECT
ST_Union(geom)::Geometry(MultiPolygon,26918) AS geom,
SubStr(blkid,1,5) AS countyid
FROM nyc_census_blocks
GROUP BY countyid;
面积测试可以确认我们的联合操作没有丢失任何几何图形。首先,我们计算每个单独的人口普查街区的面积,并将这些面积按人口普查县 ID 进行分组求和。
SELECT SubStr(blkid,1,5) AS countyid, Sum(ST_Area(geom)) AS area
FROM nyc_census_blocks
GROUP BY countyid
ORDER BY countyid;
countyid | area
----------+------------------
36005 | 110196022.906506
36047 | 181927497.678368
36061 | 59091860.6261323
36081 | 283194473.613692
36085 | 150758328.111199
然后,我们计算县表格中每个新县多边形的面积
SELECT countyid, ST_Area(geom) AS area
FROM nyc_census_counties
ORDER BY countyid;
countyid | area
----------+------------------
36005 | 110196022.906507
36047 | 181927497.678367
36061 | 59091860.6261324
36081 | 283194473.593646
36085 | 150758328.111199
相同的答案!我们已经成功地从人口普查街区数据构建了纽约市县表格。
20.5. 函数列表¶
ST_Centroid(geometry): 返回一个点几何图形,表示输入几何图形的质心。
ST_PointOnSurface(geometry): 返回一个点几何图形,该几何图形保证位于输入几何图形的内部。
ST_Buffer(geometry, distance): 对于几何图形:返回一个几何图形,表示所有距离该几何图形小于或等于距离的点。计算以该几何图形的空间参考系进行。对于地理信息:使用平面变换包装器。
ST_Intersection(geometry A, geometry B): 返回一个几何图形,表示 geomA 和 geomB 的共享部分。地理信息实现对几何图形进行变换以进行相交,然后变换回 WGS84。
ST_Union(): 返回一个几何图形,表示几何图形的点集并集。
ST_AsText(text): 返回几何/地理的 Well-Known Text (WKT) 表示,不包含 SRID 元数据。
substring(string [from int] [for int]): PostgreSQL 字符串函数,用于提取与 SQL 正则表达式匹配的子字符串。
sum(expression): PostgreSQL 聚合函数,返回一组记录中记录的总和。