繁体   English   中英

使用 PostGIS 查找最近点

[英]Find nearest point using PostGIS

在带有 PostGIS 扩展的 PostgreSQL 12 上,我有两个表定义如下:

CREATE TABLE table_a (
    id_a integer,
    id_b integer,    
    coord geometry,
);

CREATE INDEX table_a_coord_idx ON table_a USING gist (coord);

CREATE TABLE table_b (
    id_b integer,
    coord geometry,
);

CREATE INDEX table_b_coord_idx ON table_b USING gist (coord);

这两个表都有大约 300 万个条目。 coord列仅包含点几何。 id_b的值最初是 null。

我的目标是为 table_a 中的每个点找到距table_a最近的点并填写table_b id_b 我编写了一个小的 Python 脚本来通过基于索引的 KNN 搜索来实现这一点:

import psycopg2 as pg

conn = pg.connect()
cur = conn.cursor()

cnt = 0
cur.execute('SELECT id_a, coord FROM table_a WHERE id_b IS NULL')
for row in cur.fetchall():
    cnt += 1
    cur.execute('SELECT id_b FROM table_b ORDER BY geom <-> %s LIMIT 1;', (row[1],))
    nearest_vertex = cur.fetchone()
    cur.execute('UPDATE table_a SET id_b=%s WHERE id_a=%s', (nearest_vertex[0], row[0]))
    if cnt % 1000 == 0:
        conn.commit()
conn.commit()

此代码有效。 但平均需要 0.6 秒才能完成一个条目,因此完成所有条目需要大约三周的时间。

有谁知道如何加快这个过程?

在循环中逐个处理记录会导致大量网络流量流向数据库。
相反,尝试在单个语句中一次更新所有条目(如果您愿意,可以从 pyton 脚本发送)。

UPDATE table_a 
SET id_b = (
  SELECT id_b 
  FROM table_b 
  ORDER BY table_b.geom <-> table_a.geom 
  LIMIT 1
)
WHERE id_b IS NULL;

有点晚了,但我的第一枪是检查这样的查询:

-- Find the nearest hospital to each school
-- that is within 3000 units of the school.
SELECT DISTINCT ON (s.gid) s.gid, s.school_name, s.geom, h.hospital_name
    FROM schools s
        LEFT JOIN hospitals h ON ST_DWithin(s.the_geom, h.geom, 3000)
    ORDER BY s.gid, ST_Distance(s.geom, h.geom);

它来自 postgis 手册http://postgis.net/docs/manual-3.0/ST_DWithin.html 只要确保您在几何列上有索引并避免大半径。 半径越大,查询越慢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM