postgresql - 如何在 PostgreSQL 数据库中找到靠在一起的点?

标签 postgresql geocoding

我有一个 PostgreSQL 地理节点表,每个节点都有一个纬度经度。如果任何两个节点相距不到 1 公里,则很可能其中一个节点是错误创建的。

我该如何检测?

一个极慢的解决方案

“蛮力”方法基本上是,“对于每个节点,检查其他节点并查看它与第一个节点的距离。如果小于 1 公里,则将这对节点添加到列表中。”

SQL 实现将是:

SELECT
  n1.id AS n1_id, n1.latitude AS n1_lat, n1.longitude AS n1_long,
  n2.id AS n2_id, n2.latitude AS n2_lat, n2.longitude AS n2_long
FROM
  nodes n1
INNER JOIN nodes n2 ON (
  n1.id != n2.id
  AND earth_distance(
    ll_to_earth(n1.latitude, n1.longitude),
    ll_to_earth(n2.latitude, n2.longitude)
  ) < 1000
)

这太慢了;对于 N 个节点,大约有 N2 对要检查。在我的数据库上,这样做是不可行的。

最佳答案

您为什么不限制您的加入仅“附近”节点?

在表 nodes 上创建 2 个索引:

CREATE INDEX I_NODES_LAT ON NODES (LATITUDE, ID);
CREATE INDEX I_NODES_LON ON NODES (LONGITUDE, ID);
ANALYZE NODES;

其次,尝试这种方式:

SELECT
  n1.id AS n1_id, n1.latitude AS n1_lat, n1.longitude AS n1_long,
  n2.id AS n2_id, n2.latitude AS n2_lat, n2.longitude AS n2_long
FROM
  nodes n1
INNER JOIN nodes n2 ON  n1.id != n2.id

-- the trick is to get only nearby nodes. 
-- You can mess with "0.1" to restrict even more... It is just as guess...
AND N2.latitude  between (N1.latitude - 0.1)  and (N1.latitude + 0.1)
AND N2.longitude between (N1.longitude - 0.1) and (N1.longitude + 0.1) 

WHERE
  earth_distance
  (
    ll_to_earth(n1.latitude, n1.longitude),
    ll_to_earth(n2.latitude, n2.longitude)
  ) < 1000

关于postgresql - 如何在 PostgreSQL 数据库中找到靠在一起的点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26129759/

相关文章:

sql - 在 SQL (PSQL) 中,如何按行的分区进行分组(如何嵌套分组)?

function - 在 SELECT 和 WHERE 中使用 Postgresql 函数

java - 通过 java JDBC 检查 postgres 数据库中的记录是否更新

geolocation - 是否有将 Thomas Bros map 页面和网格转换为纬度/经度的公式?

iPhone 谷歌地理编码请求失败

Laravel 迁移未连接 AWS-RDS postgres(找不到驱动程序...)。 PDO 已安装。怎么解决呢?

url - Google Places API 按网址搜索

android - [安卓][谷歌地图] : Get the Address of location on touch

python - 如何对电话号码进行地理编码

postgresql - 重新创建容器后如何让 PostgresQL 使用 .env 文件中的环境变量(不删除卷)