在PostGIS中找到最接近的几何


16

我一直在研究PostGIS的“ API”功能,并且我注意到它们中的大多数需要两个元素进行比较。例如,ST_Distance函数采用两个几何/地理元素来查找距离。

没有函数可以执行以下操作:“给定几何G,在表T中给我最接近的几何GClosest,其中G.id <> GClosest.id”

我意识到我可以编写一个PL / PgSQL函数来遍历表并在每个元素上调用ST_Distance,但是我希望有一个更好,更有效的解决方案。


1
如果您对最接近的几何图形的距离感兴趣,请访问
gis.stackexchange.com/questions/11979/…– underdark

让我知道我是否理解正确...您想要下一个与最接近的功能具有相同距离的功能吗?
falcacibar 2011年

Answers:


7

您的问题也可以通过单个查询(尽管很复杂)来回答,如下所示,该查询返回整个记录和到参考几何体的距离。请注意,如果不止一个记录的最小距离比赛他们回来了。

SELECT 
  i.*,
  md.min_distance
FROM
  address AS i, 
  (SELECT 
     ga.address_geom,
     min( ST_Distance(
            ga.address_geom,
            gb.address_geom)
        ) AS min_distance
   FROM
     address AS ga,
     address AS gb 
   WHERE 
     ga.id <> gb.id 
   AND 
     ga.id = 3
   GROUP BY 
     ga.address_geom
  ) AS md 
WHERE 
  ST_Distance( i.address_geom, md.address_geom) = md.min_distance;

我已经在地址表上测试了此查询,并且可以正常工作。在上面的查询中,我正在寻找最接近id = 3的点。


这是个很好的信息-谢谢...我从定义上理解了min(..)聚合函数,但是我对在示例中如何使用它感到困惑。st_distance(X,Y)接受两个几何类型,并返回它们之间的距离,该距离是单个值。为什么然后在该单个值结果上调用聚合函数?也许我误解了内部选择语句...
Jmoney38'9

group by在ga几何上是整个结果集的常数(请记住ga由id = 3选择),因此它基本上什么也不做。这是在外部查询的st_distance中使ga几何可用而不再次连接表两次的一种技巧。今天,我在想,也许可以通过使用partition子句完全摆脱内部查询。那也应该提高性能。我会尝试的,并让您知道。
unicoletti 2011年

不幸的是,在8.4中引入了窗口函数,现在我无法访问同时具有postgis和该版本的服务器,因此我无法测试使用partion子句重写的查询。
unicoletti 2011年

7

George MacKerron编写了一个简单的Nearest Neighbor函数,我发现它非常有用。此函数将最近邻居的ID返回给定特征:

create or replace function 
  nn(nearTo                   geometry
   , initialDistance          real
   , distanceMultiplier       real 
   , maxPower                 integer
   , nearThings               text
   , nearThingsIdField        text
   , nearThingsGeometryField  text)
 returns integer as $$
declare 
  sql     text;
  result  integer;
begin
  sql := ' select ' || quote_ident(nearThingsIdField) 
      || ' from '   || quote_ident(nearThings)
      || ' where st_dwithin($1, ' 
      ||   quote_ident(nearThingsGeometryField) || ', $2 * ($3 ^ $4))'
      || ' order by st_distance($1, ' || quote_ident(nearThingsGeometryField) || ')'
      || ' limit 1';
  for i in 0..maxPower loop
     execute sql into result using nearTo              -- $1
                                , initialDistance     -- $2
                                , distanceMultiplier  -- $3
                                , i;                  -- $4
    if result is not null then return result; end if;
  end loop;
  return null;
end
$$ language 'plpgsql' stable;

用法示例:

SELECT id, nn(pt_geom,0.00001,2,100,'nw_node','node_id','node_geom') FROM my_point_table;

...为my_point_table中的每个条目选择nw_node表中最近的节点。

波士顿GIS站点上还有一个更通用的功能


我更关心如何从更一般的意义上创建查询1:N查询。例如,我可能想查找与G重叠的第一个元素,而不是找到最接近几何G的元素。无论如何,谢谢您提供的信息。与波士顿GIS的链接非常有用!我已经打印了一些备忘单:-)
Jmoney38'9

@ Jmoney48,也许您可​​以改写您的问题以使其更清晰。因此,您对特定的最近邻问题不感兴趣,而对如何将一个几何与表中的所有几何进行比较感兴趣?
昏暗

总是使用波士顿GIS站点的通用功能,对于大表来说,简单的速度实在令人难以置信,并且应用它的努力并不多。
Vladtn 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.