我有一个带有成千上万个PostGIS POINT的PostgreSQL 9.1表。对于这些,我想在另一个POINT表中找到最接近的点。第二张表中的点代表整个世界上的网格,因此我知道总会有1度以内的匹配。这是我到目前为止使用的查询,它利用了GIST索引,因此相当快(总计约30秒)。
SELECT DISTINCT ON (p.id)
p.id, ST_AsText(p.pos)
, ST_AsText(first_value(g.location) OVER (PARTITION BY p.id ORDER BY ST_Distance(p.pos, g.location::geography)))
FROM point p
JOIN grid g ON ST_DWithin(p.pos::geometry, g.location, 1)
唯一的问题是时间表。网格点的纬度只有180,而不是-180。使用ST_Distance的几何版本时,这不会在日期线的另一侧返回点。例如。如果p.pos是POINT(-179.88056 -16.68833)
最近的网格点,可能是POINT(180 -16.25)
,但是上面的查询没有返回它。解决此问题的最佳方法是什么?
我真的不希望单个网格点具有两个坐标(-180和+180)。我尝试添加自己的函数来检查这种特定情况,但随后查询在5分钟内未返回,可能是因为它无法再使用索引。我还尝试使用地理版本的ST_DWithin,并且该查询在5分钟后也没有返回。
好问题(您的回复很聪明!)。不过,人们不得不怀疑:如果该软件无法识别出-180 = 180的经度,则可能是假装这些是投影坐标,并且正在使用欧几里得算法查找最接近的点,这将产生误差(微妙的接近赤道,两极和+ -180子午线附近巨大)。我不知道这是否会在您的应用程序中导致严重的问题,但是在其他许多情况下却会导致问题,并且解决方法无法解决错误。
—
ub
很好,但是在这种情况下,客户端应用程序将不会执行其他“最接近”的计算-它只会获取与查询返回的网格点相关的一些数据。
—
EM0