在大型表格中使用PostGIS查找每个Point的最近邻居Linstring

时间:2015-03-05 22:21:43

标签: postgresql postgis

我正在尝试将表1(10k记录)中的每条记录与表中最近的邻居(20k记录)连接起来。我希望有一个解决方案,不需要我迭代表1并为每个记录执行KNN。

我试图通过合理的距离进行KNN索引限制,并从表中选择不同的表作为子查询,但这需要我按id号而不是距离排序。

非常感谢任何建议。

select distinct on (t1id) t1id, it2d, dist, name, street
from (
    select t1id, it2d, dist, name, street
    from (
        select t1id, it2d, st_distance(t1geom, t2geom) as dist, name, street
        from (
            select t1.id as t1id,t1.geom as t1geom, t2.id as t2id, t2.geom as t2geom, t1.name, t2.street
                from t1
            join t2
                on st_dwithin(t1.geom, t2.geom, 300)
            where t1.seg is null 
        ) as near
        order by t1geom <-> t2geom  
    ) as distOrdered
    order by dist 
) as idOrdered
order by t1id 

1 个答案:

答案 0 :(得分:0)

我发现了一种似乎有效的方法,但它有点难看。我查询第一个查询的结果以获取id号和最短距离,然后将其连接回原始查询以获得每条记录的最短距离。

这远非理想,但我相信正在返回正确的结果。

select t1id, it2d, dist, name, street
from (
    select t1id, it2d, dist, name, street
    from (
        select t1id, it2d, dist, name, street
        from (
            select t1id, it2d, st_distance(t1geom, t2geom) as dist, name, street
            from (
                select t1.id as t1id,t1.geom as t1geom, t2.id as t2id, t2.geom as t2geom, t1.name, t2.street
                    from t1
                join t2
                    on st_dwithin(t1.geom, t2.geom, 300)
                where t1.seg is null 
            ) as near
            order by t1geom <-> t2geom  
        ) as distOrdered
        order by dist 
    ) as idOrdered
) as allD
join (
    select distinct on (t1id) t1id, min(dist) as md
        from (
            select t1id, it2d, dist, name, street
            from (
                select t1id, it2d, st_distance(t1geom, t2geom) as dist, name, street
                from (
                    select t1.id as t1id,t1.geom as t1geom, t2.id as t2id, t2.geom as t2geom, t1.name, t2.street
                        from t1
                    join t2
                        on st_dwithin(t1.geom, t2.geom, 300)
                    where t1.seg is null 
                ) as near
                order by t1geom <-> t2geom  
            ) as distOrdered
            order by dist 
        ) as idOrdered
        group by t1id order by t1id
    ) as short
on allD.t1id = short.t1id and allD.dist = short.md