2017-04-13 92 views
1

我有一个网络表,其中的节点由数组中的整数指定,我在输入数据时已经进行了排序。整数对应于位置表中的ID,其包含空间中点的WKT表示。我如何计算从开始到结束的网络距离?下面计算有序数组中节点之间的总距离

Network Table 
--------------- 
| Nodes   | 
--------------- 
| {1,2,3}  | 
--------------- 


Location Table 
--------------- 
| ID, Point  | 
--------------- 
| 1, (1,0)  | 
| 2, (2,0)  | 
| 3, (2,1)  | 
--------------- 

最简单的情况中给出我想以产生用于上述简单的情况的值2。结果应该扩展到复杂的网络。

通过使用ST_distance我可以计算网络中所有单个点之间的距离,但我努力保留数组描述的唯一路径。

+0

什么是距离?它是从第一个到最后一个点的数量还是距离? –

+0

从第一个到最后一个,通过中间节点的距离。 – fordy

回答

0

您需要<-> operator为PostgreSQL的point型(你似乎有):

select network_id, sum(dist) 
from  (
    select  n.id network_id, point <-> lag(point) over (partition by n.id order by i) dist 
    from  network n 
    cross join unnest(nodes) i 
    join  location l on l.id = i 
) s 
group by network_id 

或者,如果你真的有几何& PostGIS,你也可以使用ST_Distance(虽然<->supported by PostGIS too,因为它是距离运营商的普遍 “形式” 反正):

select network_id, sum(dist) 
from  (
    select  n.id network_id, ST_Distance(point, lag(point) over (partition by n.id order by i)) dist 
    from  network n 
    cross join unnest(nodes) i 
    join  location l on l.id = i 
) s 
group by network_id 

http://rextester.com/ESQA1611

+0

他真正想要的是pg路由,因为它是定向的。 –

1
with network (a) as (values ('{1,2,3}'::int[])) 
, location (id, p) as (values (1,'(1,0)'::point),(2,'(2,0)'),(3,'(2,1)')) 
select a, sum(dt) 
from (
    select 
     a, 
     abs(p[0] - lag(p[0]) over(partition by a order by id)) + 
     abs(p[1] - lag(p[1]) over(partition by a order by id)) as dt 
    from 
     (
      select a, unnest(a) as id 
      from network 
     ) network 
     inner join 
     location using (id) 
) s 
group by a 
; 
    a | sum 
---------+----- 
{1,2,3} | 2 

在PostGIS:

with network (a) as (values ('{1,2,3}'::int[])) 
, location (id, p) as (values 
    (1,st_makepoint(1,0)),(2,st_makepoint(2,0)),(3,st_makepoint(2,1)) 
) 
select a, sum(dt) 
from (
    select 
     a, 
     st_distance(p, lag(p) over(partition by a order by id)) as dt 
    from 
     (
      select a, unnest(a) as id 
      from network 
     ) network 
     inner join 
     location using (id) 
) s 
group by a 
; 
    a | sum 
---------+----- 
{1,2,3} | 2