使用 ST_DWithin 获取区域内最近对象的 id

问题描述

我在 pgAdmin4 中有一个触发器函数,它可以抓取最接近 QGIS 中放置的线的起点和终点的对象。但是,我不仅要获取最近对象的 id,而且仅当对象在 20' 半径内并且对象的 id 不为空时才获取该 id。

This fiddle 有我的工作触发器(也可以在下面找到触发器的副本)以及一些示例数据。我知道我需要将 ST_DWithin 添加函数中,但我不确定如何去做。

以下是触发代码

CREATE OR REPLACE FUNCTION insert_pipe() RETURNS TRIGGER AS $$
BEGIN
  SELECT 
  j.node_id,i.node_id
  INTO NEW.dwn_str,NEW.up_str
  FROM ST_Dump(ST_SetSRID(NEW.geom,2346)) dump_line,LAteraL (SELECT s.node_id,(ST_SetSRID(s.geom,2346)) 
           FROM structures s
           ORDER BY ST_EndPoint((dump_line).geom)<->(ST_SetSRID(s.geom,2346)) 
           LIMIT 1) j (node_id,geom_closest_downstream),2346))
           FROM structures s
           ORDER BY ST_StartPoint((dump_line).geom)<->(ST_SetSRID(s.geom,2346)) 
           LIMIT 1) i (node_id,geom_closest_upstream);
           
  RETURN NEW;
END; $$ LANGUAGE plpgsql;

CREATE TRIGGER t_insert_pipe 
BEFORE INSERT OR UPDATE ON pipes FOR EACH ROW EXECUTE PROCEDURE insert_pipe();

解决方法

您很可能用错了 ST_SetSRID。顾名思义,它应该用于将 SRS 设置为错误或不存在的几何图形。但是,您的几何图形已经具有 SRS,即 EPSG:2965。因此,如果您想使用不同的 SRS 执行空间操作,并且您可以负担得起在查询时间中进行此更改(注意开销!),请使用 ST_Transform。除此之外,只需将 ST_DWithin 放在子查询的 WHERE 子句中:

CREATE OR REPLACE FUNCTION insert_pipe() RETURNS TRIGGER AS $$
BEGIN
  SELECT 
  j.node_id,i.node_id
  INTO NEW.node_id_dwn_str,NEW.node_id_up_str
  FROM ST_Dump(ST_Transform(NEW.geom,2346)) dump_line,LATERAL (SELECT s.node_id,ST_Transform(s.geom,2346) 
           FROM structures s 
           WHERE ST_DWithin((dump_line).geom,2346),your_dist)
           ORDER BY ST_EndPoint((dump_line).geom)<->(ST_Transform(s.geom,2346)) 
           LIMIT 1) j (node_id,geom_closest_downstream),(ST_Transform(s.geom,2346))
           FROM structures s
           WHERE ST_DWithin((dump_line).geom,your_dist)
           ORDER BY ST_StartPoint((dump_line).geom)<->(ST_Transform(s.geom,2346)) 
           LIMIT 1) i (node_id,geom_closest_upstream);
           
  RETURN NEW;
END; $$ LANGUAGE plpgsql;
  • 根据新 SRS 的单位将占位符 your_dist 更改为所需的距离。
  • 考虑更新几何图形以使用“正确的”SRS,而不是在查询时进行。

进一步阅读:How to use ST_Transform