POSTGIS将距离查询限制为阈值

时间:2018-11-22 03:16:42

标签: postgis

我希望从两个表中获取行之间的成对距离,并且仅返回阈值距离内的对。这些表具有大量对象,因此性能是一个需要关注的问题。

我找到了一个最接近距离的示例 PostGIS minimum distance between two large sets of points

那里的代码看起来像

SELECT 
    a.id, nn.id AS id_nn, 
    a.geom, nn.geom_closest, 
    ST_Distance_Sphere(a.geom, nn.geom_closest) AS min_dist
FROM 
    table_a AS a
    CROSS JOIN LATERAL
        (SELECT
            b.id, 
            b.geom AS geom_closest
        FROM table_b b
        ORDER BY a.geom <-> b.geom
        LIMIT 1) AS nn;

我对SQL感到很糟糕,我知道LIMIT 1在订购时最接近。

如何修改此值以使所有对都小于阈值?我尝试使用WHERE子句将其限制为一个值

SELECT 
    a.id, nn.id AS id_nn, 
    a.wkb_geometry, nn.geom_closest, 
    ST_DistanceSphere(a.wkb_geometry, nn.geom_closest) AS min_dist
FROM 
    mammography21 AS a
    CROSS JOIN LATERAL
        (SELECT
            b.gid as id, 
            b.wkb_geometry AS geom_closest
        FROM cartographic_boundary_us_zcta_2016 b
        ORDER BY a.wkb_geometry <-> b.wkb_geometry) AS nn
WHERE ST_DistanceSphere(a.wkb_geometry, nn.geom_closest) <= 10.0;

但这给出了错误: 服务器遇到内部错误,无法完成您的请求。服务器超载或应用程序错误。 即使它奏效了,我也认为这是一种低效的方法。我应该如何尝试执行此查询?

1 个答案:

答案 0 :(得分:1)

排序仅用于获取最接近的点。如果您想要多个点,则不必再按距离对点进行排序。

进行距离验证是正确的事情...但是要当心在哪里做。您的查询花费了太多时间,因为它对于每个点都计算到每个其他点(横向连接)的距离,然后对结果进行过滤以仅保留附近的点。

由于您需要的不仅仅是1点,因此可以删除以后的联接。正如@thibautg所建议的,st_Dwithin是优选的,因为它利用了空间索引。

最后,您可能需要将数据投射到地理位置以计算以米为单位的距离(取决于数据CRS)。在这种情况下,您还需要在地理位置上提供空间索引。

SELECT 
    a.id, nn.id AS id_nn, 
    a.geom srcGeom, nn.geom nearGeom, 
    ST_DistanceSphere(a.geom, nn.geom) AS near_dist
FROM 
    mammography21 AS a,
    cartographic_boundary_us_zcta_2016 nn
WHERE ST_DWithin(a.geom, nn.geom, 10);