【问题标题】:Calculate the total distance between nodes in an ordered array计算有序数组中节点之间的总距离
【发布时间】:2017-04-13 13:44:17
【问题描述】:

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

下面给出最简单的情况

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


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

我想为上面的简单情况生成值 2。结果应该扩展到复杂的网络。

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

【问题讨论】:

  • 什么是距离?是点数还是从第一个到最后一个的距离?
  • 第一个到最后一个的距离,通过中间节点。

标签: sql postgresql gis postgis


【解决方案1】:

对于 PostgreSQL 的 point 类型(您似乎拥有),您将需要 <-> operator

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(虽然&lt;-&gt;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

【讨论】:

  • 他真正想要的是 pg 路由,因为它是定向的。
【解决方案2】:
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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-29
    • 2014-11-29
    • 2017-11-03
    • 2017-04-21
    • 2014-02-28
    相关资源
    最近更新 更多