在 PgAdmin4 中尝试使用 ST_CONTAINS FOR LOOP 列
Trying to FOR LOOP a column with ST_CONTAINS in PgAdmin4
我正在使用 PgAdmin4 创建一个包含大量几何数据的视图。此数据的一部分是存在于多边形内的多段线。我正在尝试编写一个代码,可以循环遍历给定列中的所有多段线数据,并检查它是否在给定的多边形和 return true/false 中。到目前为止,这就是我所拥有的。
DO
$$
BEGIN
FOR i IN (SELECT "geom" FROM "street map"."segment_id")
LOOP
SELECT ST_CONTAINS(
(SELECT "geom" FROM "street map"."cc_districts" WHERE "district number" = 1),
(i)
)
RETURN NEXT i
END LOOP;
END
$$
我在运行这段代码时收到的错误如下:
ERROR: loop variable of loop over rows must be a record or row variable or list of scalar variables
LINE 4: FOR i IN (SELECT "geom" FROM "street map"."segment_id")
^
SQL state: 42601
Character: 18
据我了解,“i”必须指代“行变量”,我试图用这段代码定义该变量:
(SELECT "geom" FROM "street map"."segment_id")
任何实现这一目标的想法都会非常有帮助。
这里简单的连接会更有效率
SELECT line.*, polygon.id IS NOT NULL AS is_in_polygon
FROM line
LEFT JOIN polygon
ON ST_Contains(polygon.geometry, line.geometry)
AND polygon.id = 1
可译为:
获取 line
记录的每个字段,如果 polygon.id
存在 (is not null
),则获取 true
,否则获取 false
(更多内容见下文)。将此布尔字段命名为 is_in_polygon
.
在每一行都这样做。
将每条线连接 (link) 到多边形图层。如果没有匹配,保留 line
信息并为每个 polygon
字段输入 NULL
(这是一个 left join
)。如果匹配,则同时保留 line
和 polygon
信息。
如果 polygon.geometry
包含 line.geometry
且 polygon.id = 1
则找到匹配项
我找到了一种无需 JOIN
或 FOR LOOP
即可完成这项工作的方法。以下代码有效。
SELECT * FROM "street map"."segment_id"
WHERE
ST_WITHIN(
ST_CENTROID((ST_SetSRID(geom, 4326))),
ST_SetSRID((SELECT geom FROM "street map"."cc_districts" WHERE "district number" = 1),4326))
这让我可以通过在给定列中的所有行上运行该过程来实现我的意图。我从 ST_CONTAINS
换成了 ST_WITHIN
,我现在还使用 ST_CENTROID
检查多段线的质心是否在给定的多边形内。我发现通过使用 ST_SetSRID
将几何的 SRID 断言为 4326,错误消失了。我不确定为什么会这样,因为我的 geom 的 SRID 已经是 4326。
感谢所有回答的人
我正在使用 PgAdmin4 创建一个包含大量几何数据的视图。此数据的一部分是存在于多边形内的多段线。我正在尝试编写一个代码,可以循环遍历给定列中的所有多段线数据,并检查它是否在给定的多边形和 return true/false 中。到目前为止,这就是我所拥有的。
DO
$$
BEGIN
FOR i IN (SELECT "geom" FROM "street map"."segment_id")
LOOP
SELECT ST_CONTAINS(
(SELECT "geom" FROM "street map"."cc_districts" WHERE "district number" = 1),
(i)
)
RETURN NEXT i
END LOOP;
END
$$
我在运行这段代码时收到的错误如下:
ERROR: loop variable of loop over rows must be a record or row variable or list of scalar variables
LINE 4: FOR i IN (SELECT "geom" FROM "street map"."segment_id")
^
SQL state: 42601
Character: 18
据我了解,“i”必须指代“行变量”,我试图用这段代码定义该变量:
(SELECT "geom" FROM "street map"."segment_id")
任何实现这一目标的想法都会非常有帮助。
这里简单的连接会更有效率
SELECT line.*, polygon.id IS NOT NULL AS is_in_polygon
FROM line
LEFT JOIN polygon
ON ST_Contains(polygon.geometry, line.geometry)
AND polygon.id = 1
可译为:
获取 line
记录的每个字段,如果 polygon.id
存在 (is not null
),则获取 true
,否则获取 false
(更多内容见下文)。将此布尔字段命名为 is_in_polygon
.
在每一行都这样做。
将每条线连接 (link) 到多边形图层。如果没有匹配,保留 line
信息并为每个 polygon
字段输入 NULL
(这是一个 left join
)。如果匹配,则同时保留 line
和 polygon
信息。
如果 polygon.geometry
包含 line.geometry
且 polygon.id = 1
我找到了一种无需 JOIN
或 FOR LOOP
即可完成这项工作的方法。以下代码有效。
SELECT * FROM "street map"."segment_id"
WHERE
ST_WITHIN(
ST_CENTROID((ST_SetSRID(geom, 4326))),
ST_SetSRID((SELECT geom FROM "street map"."cc_districts" WHERE "district number" = 1),4326))
这让我可以通过在给定列中的所有行上运行该过程来实现我的意图。我从 ST_CONTAINS
换成了 ST_WITHIN
,我现在还使用 ST_CENTROID
检查多段线的质心是否在给定的多边形内。我发现通过使用 ST_SetSRID
将几何的 SRID 断言为 4326,错误消失了。我不确定为什么会这样,因为我的 geom 的 SRID 已经是 4326。
感谢所有回答的人