Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何根据这些表中的空间关系几何图形将数据从一个表设置到另一个表_Sql_Postgresql_Postgis - Fatal编程技术网

Sql 如何根据这些表中的空间关系几何图形将数据从一个表设置到另一个表

Sql 如何根据这些表中的空间关系几何图形将数据从一个表设置到另一个表,sql,postgresql,postgis,Sql,Postgresql,Postgis,我有两个数据表。我需要根据这些表中数据之间的空间关系将数据构建从一个表设置到另一个表。源表中的空间数据为多边形类型,目标表中的空间数据为点。我查询了相交的点和多边形。很好用。但也有一些点与多边形不相交。我的想法是为这些点中的每一个定义最近的多边形,并从中获取建筑物的值。为此,我编写了一个函数,它获取点的id并返回building_h值。在测试中,它工作正常 CREATE OR REPLACE FUNCTION closest_pol(int4) RETURNS NUMERIC AS $$ DE

我有两个数据表。我需要根据这些表中数据之间的空间关系将数据构建从一个表设置到另一个表。源表中的空间数据为多边形类型,目标表中的空间数据为点。我查询了相交的点和多边形。很好用。但也有一些点与多边形不相交。我的想法是为这些点中的每一个定义最近的多边形,并从中获取建筑物的值。为此,我编写了一个函数,它获取点的id并返回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 = $1
                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;
但是,当我对整个表运行查询时,它将永远执行。。(对于约3000行,具有空值)。它持续了好几个小时才停下来

UPDATE building_from_landuse_spgg AS bfl SET 
    building_h = (SELECT closest_pol(bfl.id))
    WHERE bfl.building_h IS NULL;

你知道我做错了什么吗?

在你的
WHERE
子句中,你使用的
ST_与查询时间内创建的0.006缓冲区相交。考虑使用您的这个缓冲区使用部分<代码> GIST< /代码>索引(如果出于任何原因,您必须使用它们):

我认为不需要函数,因为可以在
UPDATE
语句中将函数内部的查询用作子查询。但是如果您有坚持使用该函数的理由,您可以取消
选择
来调用它:

UPDATE building_from_landuse_spgg 
SET building_h = closest_pol(id)
WHERE building_h IS NULL;
编辑:正如@JGH正确提到的(参见注释),使用缓冲区比简单地使用缓冲区效率低。因此,如果您负担得起,请在
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
值放在第一个类中

并且可能考虑将函数的代码放在子查询中,例如

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;
进一步阅读:


您能添加两个查询的
解释吗?不要使用缓冲区,而是
st_dwithin
。不要按交叉点排序,而是按距离排序使用
st_dwithin
将更有效,并将导致更准确的结果,因为缓冲区只是一个近似值。@JGH我完全同意。我只是坚持在OP中使用的函数,但你是对的。。圣德维辛是一个更好的选择:)干杯
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;