如何根据这些 table 中的空间关系几何将数据从 table 设置到另一个
How can I set data from on table to another according spatial relation geometries in these tables
我有两个 table 有数据。关于这些 table 中数据之间的空间关系,我需要将数据 building_h 从一个 table 设置到另一个。源 table 中的空间数据是多边形类型,目标 table 中的空间数据是点。我查询了相交的点和多边形。它很好用。但是有些点不与多边形相交。我的想法是为这些点中的每一个定义最接近的多边形并从中获取 building_h 值。为此,我编写了函数,该函数采用点的 id 和 returns building_h 值。并且在测试中运行正常。
CREATE OR REPLACE FUNCTION closest_pol(int4)
RETURNS NUMERIC
AS
$$
DECLARE
retVal NUMERIC;
BEGIN
SELECT bgs.building_h INTO retVal
FROM buildings_geoalert_spgg bgs, building_from_landuse_spgg bfl
WHERE ST_INTERSECTS(bgs.geom, ST_BUFFER(bfl.geom_centr, 0.0006,'quad_segs=8')) AND bfl.id =
ORDER BY ST_INTERSECTION(bgs.geom, ST_BUFFER(bfl.geom_centr, 0.0006,'quad_segs=8')) ASC
LIMIT 1;
RETURN retVal;
END;
$$
LANGUAGE plpgsql
STABLE
RETURNS NULL ON NULL INPUT;
但是当我 运行 查询整个 table 时,它会永远执行……(约 3000 行具有 NULL 值)。持续了几个小时才停止。
UPDATE building_from_landuse_spgg AS bfl SET
building_h = (SELECT closest_pol(bfl.id))
WHERE bfl.building_h IS NULL;
你知道我做错了什么吗?
在您的 WHERE
子句中,您使用 ST_Intersects
和在查询时创建的 0.006 缓冲区。考虑对你的这个缓冲区使用部分 gist
索引(如果出于某种原因你必须使用它们):
CREATE INDEX idx_buffer ON building_from_landuse_spgg USING gist (ST_Buffer(geom_centr, 0.0006,'quad_segs=8'));
我认为您不需要为此使用函数,因为您可以将函数内部的查询用作 UPDATE
语句中的子查询。但是如果你有理由坚持这个功能,你可以去掉 SELECT
来调用它:
UPDATE building_from_landuse_spgg
SET building_h = closest_pol(id)
WHERE building_h IS NULL;
编辑:正如@JGH 正确提到的(见评论),使用缓冲区的效率低于简单地使用 ST_DWithin
。因此,如果您负担得起,请在 WHERE
子句中使用的几何图形中创建一个索引 ..
CREATE INDEX idx_landuse_geom_centr ON building_from_landuse_spgg USING gist (geom_centr);
CREATE INDEX idx_geoalert_geom ON buildings_geoalert_spgg USING gist (geom);
.. 以及部分索引 building_h
会加快速度,因为您只对 NULL
记录感兴趣:
CREATE INDEX idx_landuse_building_h ON building_from_landuse_spgg (building_h)
WHERE building_h IS NULL;
或者,如果您更喜欢更广泛的索引,但仍将 NULL
值放在 前 class ..
CREATE INDEX idx_landuse_building_h ON building_from_landuse_spgg
(building_h NULLS FIRST);
也许可以考虑将函数代码放在子查询中,例如
UPDATE building_from_landuse_spgg AS bfl
SET building_h = (
SELECT bgs.building_h
FROM buildings_geoalert_spgg bgs
WHERE ST_DWithin(bgs.geom, bfl.geom_centr, 0.0006)
ORDER BY ST_Distance(bgs.geom, bfl.geom_centr) ASC LIMIT 1)
WHERE bfl.building_h IS NULL;
延伸阅读:
我有两个 table 有数据。关于这些 table 中数据之间的空间关系,我需要将数据 building_h 从一个 table 设置到另一个。源 table 中的空间数据是多边形类型,目标 table 中的空间数据是点。我查询了相交的点和多边形。它很好用。但是有些点不与多边形相交。我的想法是为这些点中的每一个定义最接近的多边形并从中获取 building_h 值。为此,我编写了函数,该函数采用点的 id 和 returns building_h 值。并且在测试中运行正常。
CREATE OR REPLACE FUNCTION closest_pol(int4)
RETURNS NUMERIC
AS
$$
DECLARE
retVal NUMERIC;
BEGIN
SELECT bgs.building_h INTO retVal
FROM buildings_geoalert_spgg bgs, building_from_landuse_spgg bfl
WHERE ST_INTERSECTS(bgs.geom, ST_BUFFER(bfl.geom_centr, 0.0006,'quad_segs=8')) AND bfl.id =
ORDER BY ST_INTERSECTION(bgs.geom, ST_BUFFER(bfl.geom_centr, 0.0006,'quad_segs=8')) ASC
LIMIT 1;
RETURN retVal;
END;
$$
LANGUAGE plpgsql
STABLE
RETURNS NULL ON NULL INPUT;
但是当我 运行 查询整个 table 时,它会永远执行……(约 3000 行具有 NULL 值)。持续了几个小时才停止。
UPDATE building_from_landuse_spgg AS bfl SET
building_h = (SELECT closest_pol(bfl.id))
WHERE bfl.building_h IS NULL;
你知道我做错了什么吗?
在您的 WHERE
子句中,您使用 ST_Intersects
和在查询时创建的 0.006 缓冲区。考虑对你的这个缓冲区使用部分 gist
索引(如果出于某种原因你必须使用它们):
CREATE INDEX idx_buffer ON building_from_landuse_spgg USING gist (ST_Buffer(geom_centr, 0.0006,'quad_segs=8'));
我认为您不需要为此使用函数,因为您可以将函数内部的查询用作 UPDATE
语句中的子查询。但是如果你有理由坚持这个功能,你可以去掉 SELECT
来调用它:
UPDATE building_from_landuse_spgg
SET building_h = closest_pol(id)
WHERE building_h IS NULL;
编辑:正如@JGH 正确提到的(见评论),使用缓冲区的效率低于简单地使用 ST_DWithin
。因此,如果您负担得起,请在 WHERE
子句中使用的几何图形中创建一个索引 ..
CREATE INDEX idx_landuse_geom_centr ON building_from_landuse_spgg USING gist (geom_centr);
CREATE INDEX idx_geoalert_geom ON buildings_geoalert_spgg USING gist (geom);
.. 以及部分索引 building_h
会加快速度,因为您只对 NULL
记录感兴趣:
CREATE INDEX idx_landuse_building_h ON building_from_landuse_spgg (building_h)
WHERE building_h IS NULL;
或者,如果您更喜欢更广泛的索引,但仍将 NULL
值放在 前 class ..
CREATE INDEX idx_landuse_building_h ON building_from_landuse_spgg
(building_h NULLS FIRST);
也许可以考虑将函数代码放在子查询中,例如
UPDATE building_from_landuse_spgg AS bfl
SET building_h = (
SELECT bgs.building_h
FROM buildings_geoalert_spgg bgs
WHERE ST_DWithin(bgs.geom, bfl.geom_centr, 0.0006)
ORDER BY ST_Distance(bgs.geom, bfl.geom_centr) ASC LIMIT 1)
WHERE bfl.building_h IS NULL;
延伸阅读: