【问题标题】:Using ST_DWithin in subquery (PostGIS)在子查询中使用 ST_DWithin (PostGIS)
【发布时间】:2012-08-24 08:49:49
【问题描述】:

我有一个带点的几何表。所有点都有唯一的 ID。现在我想进行查询,选择一个点(id 为 34567)并围绕该点进行 5 公里的缓冲区分析。我的目标是选择距离所选点超过 5 公里的所有点。所有数据都存储在一个表中。

我已经尝试了以下,

SELECT D.id, D.geometry, S.id, S.geometry
FROM points AS D, points AS S
WHERE not ST_DWithin(D.geometry, S.geometry, 5000) AND D.id not like '34567'

但查询会永远运行下去。

我做错了什么?

感谢所有答案

【问题讨论】:

  • 很高兴知道您找到了解决方案,感谢分享! xkcd.com/979
  • @Pierre,不错的链接。我无法告诉你这种情况发生了多少次。

标签: subquery postgis


【解决方案1】:

最初编写的查询是回答此问题的一种非常低效的方式,因为它本质上涉及空间自连接,而实际上,OP 只想知道距离单点超过 5 公里的点编号=34567。如果您想为每个点找到距离所有其他点超过 5 公里的所有点,则将使用自连接,这本质上是一个 0(n^2) 操作。

对原始查询的解释将显示一个嵌套循环,其中包含两个全序列扫描(即点 A 和点 B)以及 ST_DWithin 的空间连接。

查询可以更好地写成

SELECT count(S.id) FROM points AS S WHERE not ST_Dwithin(S.geometry, 
(select geometry from points where id=34567), 5000);

假设 id 上有一个索引,geometry 上有一个空间索引。

【讨论】:

    【解决方案2】:

    感谢约翰·巴萨。我是新手,但 PostGIS 手册中的所有示例都包含 geom 特征作为文本,这在日常生活中不太实用。 问题是结果还将返回作为参考的点(34567)。所以设置距离为0,返回原点,或者count=1。 我想最快的解决方案是做一个EXCEPT:

    SELECT S.id, S.geometry FROM points AS S WHERE not ST_Dwithin(S.geometry, 
    (select geometry from points where id=34567), 5000)
    EXCEPT
    SELECT S.id from POINTS where id=34567
    

    但是你必须输入两次id,这对我来说也不是很有效。

    【讨论】:

      猜你喜欢
      • 2019-02-23
      • 1970-01-01
      • 1970-01-01
      • 2017-03-07
      • 1970-01-01
      • 2011-12-08
      • 2013-10-20
      • 1970-01-01
      • 2011-04-03
      相关资源
      最近更新 更多