pgr_findCloseEdges

pgr_findCloseEdges -查找点几何图形的闭合边。

_images/boost-inside.jpeg

Boost 图内部

可用性

  • 版本 3.4.0

描述

pgr_findCloseEdges - 一个用于找到离点几何最近的边的实用函数。

  • 几何图形必须位于同一坐标系中(具有相同的 SRID)。

  • 可以获取计算代码,以便根据应用需要进行进一步的具体调整。

  • 空运行执行时返回 EMTPY SET

签名

总结

pgr_findCloseEdges(Edges SQL, point, tolerance, [options])
pgr_findCloseEdges(Edges SQL, points, tolerance, [options])
options: [cap, partial, dryrun]
返回集合 (edge_id, fraction, side, distance, geom, edge)
OR EMPTY SET

一个点

pgr_findCloseEdges(Edges SQL, point, tolerance, [options])
options: [cap, partial, dryrun]
返回集合 (edge_id, fraction, side, distance, geom, edge)
OR EMPTY SET
示例:

有默认值

  • 默认: cap => 1

    • 最多回答一行。

  • 默认: partial => true

    • 尽可能减少计算。

  • 默认: dryrun => false

    • 过程查询

  • 返回

    • edge_id, fraction, side 列的值。

    • distance, geom, edge``列上为``NULL

SELECT  *
FROM pgr_findCloseEdges(
  $$SELECT id, geom FROM edges$$,
  (SELECT geom FROM pointsOfInterest WHERE pid = 5),
  0.5);
 edge_id | fraction | side | distance | geom | edge
---------+----------+------+----------+------+------
       5 |      0.8 | l    |          |      |
(1 row)

多点

pgr_findCloseEdges(Edges SQL, points, tolerance, [options])
options: [cap, partial, dryrun]
返回集合 (edge_id, fraction, side, distance, geom, edge)
OR EMPTY SET
示例:

最多找出 \(2\) 接近兴趣点表上所有顶点的边。

每点一个答案,越小越好。

SELECT edge_id, round(fraction::numeric, 2) AS fraction, side, ST_AsText(geom) AS original_point
FROM pgr_findCloseEdges(
  $$SELECT id, geom FROM edges$$,
  (SELECT array_agg(geom) FROM pointsOfInterest),
  0.5);
 edge_id | fraction | side | original_point
---------+----------+------+----------------
       1 |     0.40 | l    | POINT(1.8 0.4)
       6 |     0.30 | r    | POINT(0.3 1.8)
      12 |     0.60 | l    | POINT(2.6 3.2)
      15 |     0.40 | r    | POINT(4.2 2.4)
       5 |     0.80 | l    | POINT(2.9 1.8)
       4 |     0.70 | r    | POINT(2.2 1.7)
(6 rows)

返回了带有值的列 edge_id, fraction, sidegeom

geom 包含原始的点几何信息,以帮助确定该行属于哪个点几何。

参数

参数

类型

描述

Edges SQL

TEXT

Edges SQL 如下所述。

point

POINT

点几何

points

POINT[]

点几何数组

tolerance

FLOAT

几何图形之间的最大距离

可选参数

参数

类型

默认

描述

cap

INTEGER

\(1\)

限制输出行数

partial

BOOLEAN

true

  • 当为 true 时,只计算 withPoints - 类别 需要的列。

  • 当为 false 时,所有的列都计算

dryrun

BOOLEAN

false

  • 当为 false 时,执行计算。

  • 当为 true 时,不执行计算,并在 PostgreSQL 的 NOTICE 中显示执行计算的查询。

内部查询

Edges SQL

类型

描述

id

ANY-INTEGER

边的标识符。

geom

geometry

边的 LINESTRING 几何。

结果列

返回集合 (edge_id, fraction, side, distance, geom, edge)

类型

描述

edge_id

BIGINT

边的标识符。

  • \(cap = 1\) 时,它是最近的边。

fraction

FLOAT

在 <0,1> 范围内的值,表示相对于边的第一个端点的相对位置。

side

CHAR

[r, l] 中的值指示该点是否为:

  • 在右边的 r

  • 在左边的 l

    • 当点在直线上时,它被认为是在右边。

distance

FLOAT

点到边缘的距离。

geom

geometry

POINT 几何

  • 一个点:包含边缘上距边缘起点一小部分的点。

  • 多个点:包含对应的 原始点

edge

geometry

原始点 到具有标识符 edge_id 的边的最近点的 LINESTRING 几何图形

单一点的结果

  • 绿色节点是 原始点

  • 几何 geom\(sp \rightarrow ep\) 边上的一个点。

  • 几何 edge 是连接 original pointgeom 的线

digraph G {
  splines=false;
  subgraph cluster0 {
    point [shape=circle;style=filled;color=green];
    geom [shape=point;color=black;size=0];
    sp, ep;

    edge[weight=0];
    point -> geom [dir=none; penwidth=0, color=red];
    edge[weight=2];
    sp -> geom -> ep [dir=none;penwidth=3 ];

    {rank=same; point, geom}
  }

  subgraph cluster1 {
    point1 [shape=circle;style=filled;color=green;label=point];
    geom1 [shape=point;color=deepskyblue; xlabel="geom"; width=0.3];
    sp1 [label=sp]; ep1 [label=ep];

    edge[weight=0];
    point1 -> geom1 [weight=0, penwidth=3, color=red,
                   label="edge"];
    edge[weight=2];
    sp1 -> geom1 -> ep1 [dir=none;weight=1, penwidth=3 ];


    geom1 -> point1 [dir=none;weight=0, penwidth=0, color=red];
    {rank=same; point1, geom1}
  }
}

多点成果

  • 绿色节点为 原始点

  • 标为 g1g2 的几何体 geom原始点

  • 标为 edge1edge2 的几何图形 edge 是一条连接 ** 原始点** 和 \(sp \rightarrow ep\) 边上最近点的线。

digraph G {
  splines = false;
  subgraph cluster0 {
     p1 [shape=circle;style=filled;color=green];
     g1 [shape=point;color=black;size=0];
     g2 [shape=point;color=black;size=0];
     sp, ep;
     p2 [shape=circle;style=filled;color=green];

     sp -> g1 [dir=none;weight=1, penwidth=3 ];
     g1 -> g2 [dir=none;weight=1, penwidth=3 ];
     g2 -> ep [weight=1, penwidth=3 ];

     g2 -> p2 [dir=none;weight=0, penwidth=0, color=red, partiallen=3];
     p1 -> g1 [dir=none;weight=0, penwidth=0, color=red, partiallen=3];
     p1 -> {g1, g2} [dir=none;weight=0, penwidth=0, color=red;]

     {rank=same; p1; g1}
     {rank=same; p2; g2}
  }
  subgraph cluster1 {
     p3 [shape=circle;style=filled;color=deepskyblue;label=g1];
     g3 [shape=point;color=black;size=0];
     g4 [shape=point;color=black;size=0];
     sp1 [label=sp]; ep1 [label=ep];
     p4 [shape=circle;style=filled;color=deepskyblue;label=g2];

     sp1 -> g3 [dir=none;weight=1, penwidth=3 ];
     g3 -> g4 [dir=none;weight=1, penwidth=3,len=10];
     g4 -> ep1 [weight=1, penwidth=3, len=10];

     g4 -> p4 [dir=back;weight=0, penwidth=3, color=red, partiallen=3,
                    label="edge2"];
     p3 -> g3 [weight=0, penwidth=3, color=red, partiallen=3,
                    label="edge1"];
     p3 -> {g3, g4} [dir=none;weight=0, penwidth=0, color=red];

     {rank=same; p3; g3}
     {rank=same; p4; g4}
  }
}

其他示例

单点示例

最多两个答案

  • cap => 2

    • 最多回答两行。

  • 默认: partial => true

    • 尽可能减少计算。

  • 默认: dryrun => false

    • 过程查询

SELECT *
FROM pgr_findCloseEdges(
  $$SELECT id, geom FROM edges$$,
  (SELECT geom FROM pointsOfInterest WHERE pid = 5),
  0.5, cap => 2);
 edge_id |      fraction      | side |      distance       | geom | edge
---------+--------------------+------+---------------------+------+------
       5 |                0.8 | l    | 0.10000000000000009 |      |
       8 | 0.8999999999999999 | r    | 0.19999999999999996 |      |
(2 rows)

了解结果

  • NULLgeom, edge

  • edge_id 靠近 原始点 的边的标识符

    • 有两条边与 原始点 : \({5, 8}\) 的距离在 \(0.5\) 单位范围内

  • 对于边 \(5\):

    • fraction:离 原始点 最近的点位于边 \(5\) 处的 \(0.8\) 分数位置。

    • side原始点 位于边 \(5\) 的左侧。

    • distance原始点 位于边 \(5\)\(0.1\) 长度单位处。

  • 对于边 \(8\)

    • fraction:离 原始点 最近的点位于边 \(8\)\(0.89..\) 分数位置。

    • side原始点 位于边 \(8\) 的右侧。

    • distance原始点 距离边 \(8\)\(0.19..\) 长度单位。

一个答案,所有列

  • 默认: cap => 1

    • 最多回答一行。

  • partial => false

    • 计算所有列

  • 默认: dryrun => false

    • 过程查询

SELECT edge_id, round(fraction::numeric, 2) AS fraction, side, round(distance::numeric, 3) AS distance,
  ST_AsText(geom) AS new_point,
  ST_AsText(edge) AS original_to_new_point
FROM pgr_findCloseEdges(
  $$SELECT id, geom FROM edges$$,
  (SELECT geom FROM pointsOfInterest WHERE pid = 5),
  0.5, partial => false);
 edge_id | fraction | side | distance |  new_point   |   original_to_new_point
---------+----------+------+----------+--------------+---------------------------
       5 |     0.80 | l    |    0.100 | POINT(3 1.8) | LINESTRING(2.9 1.8,3 1.8)
(1 row)

了解结果

  • edge_id原始点接近 的边的标识符

    • 从距离 原始点 不超过 \(0.5\) 距离单位的所有边中,边 \({5}\) 是最近的一条。

  • 对于边 \(5\):

    • fraction:离 原始点 最近的点位于边 \(5\) 处的 \(0.8\) 分数位置。

    • side原始点 位于边 \(5\) 的左侧。

    • distance原始点 位于边 \(5\)\(0.1\) 长度单位处。

    • geom:包含了从 原始点 到边 \(5\) 上最近点的几何形状。

    • edge:包含了从 原始点 到边 \(5\) geom 上最近点的 LINESTRING 几何形状

所有列最多有两个答案

  • cap => 2

    • 最多回答两行。

  • partial => false

    • 计算所有列

  • 默认: dryrun => false

    • 过程查询

SELECT edge_id, round(fraction::numeric, 2) AS fraction, side, round(distance::numeric, 3) AS distance,
  ST_AsText(geom) AS new_point,
  ST_AsText(edge) AS original_to_new_point
FROM pgr_findCloseEdges(
  $$SELECT id, geom FROM edges$$,
  (SELECT geom FROM pointsOfInterest WHERE pid = 5),
  0.5, cap => 2, partial => false);
 edge_id | fraction | side | distance |  new_point   |   original_to_new_point
---------+----------+------+----------+--------------+---------------------------
       5 |     0.80 | l    |    0.100 | POINT(3 1.8) | LINESTRING(2.9 1.8,3 1.8)
       8 |     0.90 | r    |    0.200 | POINT(2.9 2) | LINESTRING(2.9 1.8,2.9 2)
(2 rows)

了解结果:

  • edge_id 靠近 原始点 的边的标识符

    • 有两条边与 原始点 : \({5, 8}\) 的距离在 \(0.5\) 单位范围内

  • 对于边 \(5\):

    • fraction:离 原始点 最近的点位于边 \(5\) 处的 \(0.8\) 分数位置。

    • side原始点 位于边 \(5\) 的左侧。

    • distance原始点 位于边 \(5\)\(0.1\) 长度单位处。

    • geom:包含了从 原始点 到边 \(5\) 上最近点的几何形状。

    • edge:包含了从 原始点 到边 \(5\) geom 上最近点的 LINESTRING 几何形状

  • 对于边 \(8\)

    • fraction:离 原始点 最近的点位于边 \(8\)\(0.89..\) 分数位置。

    • side原始点 位于边 \(8\) 的右侧。

    • distance原始点 距离边 \(8\)\(0.19..\) 长度单位。

    • geom:包含了从 原始点 到边 \(8\) 上最近点的几何形状。

    • edge:包含了从 原始点 到边 \(8\) geom 上最近点的 LINESTRING 几何形状

单点模拟执行

  • 返回 EMPTY SET

  • partial => true

    • 被忽略

    • 由于这是一次 模拟 执行,所有计算的代码都显示在 PostgreSQL 的 NOTICE 中。

  • dryrun => true

    • 不处理查询

    • 生成一个包含用于计算所有列的代码的 PostgreSQL NOTICE

      • 代码中使用了 cap原始点

SELECT *
FROM pgr_findCloseEdges(
  $$SELECT id, geom FROM edges$$,
  (SELECT geom FROM pointsOfInterest WHERE pid = 5),
  0.5,
  dryrun => true);
NOTICE:
    WITH
    edges_sql AS (SELECT id, geom FROM edges),
    point_sql AS (SELECT '01010000003333333333330740CDCCCCCCCCCCFC3F'::geometry AS point)

    SELECT
      id::BIGINT AS edge_id,
      ST_LineLocatePoint(geom, point) AS fraction,
      CASE WHEN ST_Intersects(ST_Buffer(geom, 0.5, 'side=right endcap=flat'), point)
           THEN 'r'
           ELSE 'l' END::CHAR AS side,

        geom <-> point AS distance,
        ST_ClosestPoint(geom, point) AS new_point,
        ST_MakeLine(point, ST_ClosestPoint(geom, point)) AS new_line

    FROM  edges_sql, point_sql
    WHERE ST_DWithin(geom,  point, 0.5)
    ORDER BY geom <-> point LIMIT 1

 edge_id | fraction | side | distance | geom | edge
---------+----------+------+----------+------+------
(0 rows)

多点示例

每个点最多两个答案

  • cap => 2

    • 最多回答两行。

  • 默认: partial => true

    • 尽可能减少计算。

  • 默认: dryrun => false

    • 过程查询

SELECT edge_id, round(fraction::numeric, 2) AS fraction, side, round(distance::numeric, 3) AS distance,
  ST_AsText(geom) AS geom_is_original, edge
FROM pgr_findCloseEdges(
  $$SELECT id, geom FROM edges$$,
  (SELECT array_agg(geom) FROM pointsOfInterest),
  0.5, cap => 2);
 edge_id | fraction | side | distance | geom_is_original | edge
---------+----------+------+----------+------------------+------
       1 |     0.40 | l    |    0.200 | POINT(1.8 0.4)   |
       6 |     0.30 | r    |    0.200 | POINT(0.3 1.8)   |
      12 |     0.60 | l    |    0.200 | POINT(2.6 3.2)   |
      11 |     1.00 | l    |    0.447 | POINT(2.6 3.2)   |
      15 |     0.40 | r    |    0.200 | POINT(4.2 2.4)   |
       9 |     1.00 | l    |    0.447 | POINT(4.2 2.4)   |
       5 |     0.80 | l    |    0.100 | POINT(2.9 1.8)   |
       8 |     0.90 | r    |    0.200 | POINT(2.9 1.8)   |
       4 |     0.70 | r    |    0.200 | POINT(2.2 1.7)   |
       8 |     0.20 | r    |    0.300 | POINT(2.2 1.7)   |
(10 rows)

了解结果

  • edge``为``NULL

  • edge_id``是与一个 **原始点** (``geom)靠近的边的标识符

    • 每个 原始点 中,最多有两条边位于距离不超过 \(0.5\) 距离单位的范围内:

      • 对于 POINT(1.8 0.4)POINT(0.3 1.8) ,只找到一条边。

      • 其余的点有两条边。

  • 对于点 POINT(2.9 1.8)

    • \(5\)\(8\) 之前,因此边 \(5\)POINT(2.9 1.8) 的距离最短。

    • 对于边 \(5\):

      • fraction:离 原始点 最近的点位于边 \(5\) 处的 \(0.8\) 分数位置。

      • side原始点 位于边 \(5\) 的左侧。

      • distance原始点 位于边 \(5\)\(0.1\) 长度单位处。

    • 对于边 \(8\)

      • fraction:离 原始点 最近的点位于边 \(8\)\(0.89..\) 分数位置。

      • side原始点 位于边 \(8\) 的右侧。

      • distance原始点 距离边 \(8\)\(0.19..\) 长度单位。

每点一个答案,所有列

  • 默认: cap => 1

    • 最多回答一行。

  • partial => false

    • 计算所有列

  • 默认: dryrun => false

    • 过程查询

SELECT edge_id, round(fraction::numeric, 2) AS fraction, side, round(distance::numeric, 3) AS distance,
  ST_AsText(geom) AS geom_is_original,
  ST_AsText(edge) AS original_to_new_point
FROM pgr_findCloseEdges(
  $$SELECT id, geom FROM edges$$,
  (SELECT array_agg(geom) FROM pointsOfInterest),
  0.5, partial => false);
 edge_id | fraction | side | distance | geom_is_original |   original_to_new_point
---------+----------+------+----------+------------------+---------------------------
       1 |     0.40 | l    |    0.200 | POINT(1.8 0.4)   | LINESTRING(1.8 0.4,2 0.4)
       6 |     0.30 | r    |    0.200 | POINT(0.3 1.8)   | LINESTRING(0.3 1.8,0.3 2)
      12 |     0.60 | l    |    0.200 | POINT(2.6 3.2)   | LINESTRING(2.6 3.2,2.6 3)
      15 |     0.40 | r    |    0.200 | POINT(4.2 2.4)   | LINESTRING(4.2 2.4,4 2.4)
       5 |     0.80 | l    |    0.100 | POINT(2.9 1.8)   | LINESTRING(2.9 1.8,3 1.8)
       4 |     0.70 | r    |    0.200 | POINT(2.2 1.7)   | LINESTRING(2.2 1.7,2 1.7)
(6 rows)

了解结果

  • edge_id原始点接近 的边的标识符

    • 从距离 原始点 不超过 \(0.5\) 距离单位的所有边中,边 \({5}\) 是最近的一条。

  • 对于 原始点 POINT(2.9 1.8)

    • \(5\) 是距离 原始点 最近的边

    • fraction:离 原始点 最近的点位于边 \(5\) 处的 \(0.8\) 分数位置。

    • side原始点 位于边 \(5\) 的左侧。

    • distance原始点 位于边 \(5\)\(0.1\) 长度单位处。

    • geom:包含了 原始点 的几何形状,即 POINT(2.9 1.8)

    • edge:包含了 原始点geom)到最接近的边上的 LINESTRING 几何形状。

多点模拟执行

  • 返回 EMPTY SET

  • partial => true

    • 被忽略

    • 由于这是一次 模拟 执行,所有计算的代码都显示在 PostgreSQL 的 NOTICE 中。

  • dryrun => true

    • 不处理查询

    • 生成一个包含用于计算所有列的代码的 PostgreSQL NOTICE

      • 代码中使用了 cap原始点

SELECT *
FROM pgr_findCloseEdges(
  $$SELECT id, geom FROM edges$$,
  (SELECT array_agg(geom) FROM pointsOfInterest),
  0.5,
  dryrun => true);
NOTICE:
WITH
edges_sql AS (SELECT id, geom FROM edges),
point_sql AS (SELECT unnest('{0101000000CDCCCCCCCCCCFC3F9A9999999999D93F:0101000000CDCCCCCCCCCC10403333333333330340:0101000000CDCCCCCCCCCC04409A99999999990940:0101000000333333333333D33FCDCCCCCCCCCCFC3F:01010000003333333333330740CDCCCCCCCCCCFC3F:01010000009A99999999990140333333333333FB3F}'::geometry[]) AS point),
results AS (
  SELECT
    id::BIGINT AS edge_id,
    ST_LineLocatePoint(geom, point) AS fraction,
    CASE WHEN ST_Intersects(ST_Buffer(geom, 0.5, 'side=right endcap=flat'), point)
         THEN 'r'
         ELSE 'l' END::CHAR AS side,
    geom <-> point AS distance,
    point,
    ST_MakeLine(point, ST_ClosestPoint(geom, point)) AS new_line
  FROM  edges_sql, point_sql
  WHERE ST_DWithin(geom, point, 0.5)
  ORDER BY geom <-> point),
prepare_cap AS (
  SELECT row_number() OVER (PARTITION BY point ORDER BY point, distance) AS rn, *
  FROM results)
SELECT edge_id, fraction, side, distance, point, new_line
FROM prepare_cap
WHERE rn <= 1

 edge_id | fraction | side | distance | geom | edge
---------+----------+------+----------+------+------
(0 rows)

最多找到两条到达给定点的路线

使用 pgr_withPoints -拟议

SELECT * FROM pgr_withPoints(
  $e$ SELECT * FROM edges $e$,
  $p$ SELECT edge_id, round(fraction::numeric, 2) AS fraction, side
      FROM pgr_findCloseEdges(
        $$SELECT id, geom FROM edges$$,
        (SELECT geom FROM pointsOfInterest WHERE pid = 5),
        0.5, cap => 2)
  $p$,
  1, ARRAY[-1, -2]);
 seq | path_seq | end_pid | node | edge | cost | agg_cost
-----+----------+---------+------+------+------+----------
   1 |        1 |      -2 |    1 |    6 |    1 |        0
   2 |        2 |      -2 |    3 |    7 |    1 |        1
   3 |        3 |      -2 |    7 |    8 |  0.9 |        2
   4 |        4 |      -2 |   -2 |   -1 |    0 |      2.9
   5 |        1 |      -1 |    1 |    6 |    1 |        0
   6 |        2 |      -1 |    3 |    7 |    1 |        1
   7 |        3 |      -1 |    7 |    8 |    1 |        2
   8 |        4 |      -1 |   11 |    9 |    1 |        3
   9 |        5 |      -1 |   16 |   16 |    1 |        4
  10 |        6 |      -1 |   15 |    3 |    1 |        5
  11 |        7 |      -1 |   10 |    5 |  0.8 |        6
  12 |        8 |      -1 |   -1 |   -1 |    0 |      6.8
(12 rows)

兴趣点表

处理图外的点。

兴趣点

有时应用程序会“即时执行”,从不是图中顶点的位置开始。在pgRouting中,这些位置被称为兴趣点。

兴趣点所需的信息包括 pid, edge_id, side, fraction

在这份文档中,将有6个固定的兴趣点,并且它们将被存储在一个表中。

描述

pid

唯一标识符。

edge_id

允许到达该点的最近边的标识符。

side

它位于边 edge_id 的左侧、右侧还是两侧

fraction

该点位于边的哪个位置。

geom

点的几何形状。

newPoint

在线段顶部移动的点的几何形状。

CREATE TABLE pointsOfInterest(
    pid BIGSERIAL PRIMARY KEY,
    edge_id BIGINT,
    side CHAR,
    fraction FLOAT,
    geom geometry);
CREATE TABLE

兴趣点填充

INSERT INTO pointsOfInterest (edge_id, side, fraction, geom) VALUES
(1, 'l' , 0.4, ST_POINT(1.8, 0.4)),
(15, 'r' , 0.4, ST_POINT(4.2, 2.4)),
(12, 'l' , 0.6, ST_POINT(2.6, 3.2)),
(6, 'r' , 0.3, ST_POINT(0.3, 1.8)),
(5, 'l' , 0.8, ST_POINT(2.9, 1.8)),
(4, 'b' , 0.7, ST_POINT(2.2, 1.7));
INSERT 0 6

连接不连通的组件

要获取图的连通性:

SELECT * FROM pgr_connectedComponents(
  'SELECT id, source, target, cost, reverse_cost FROM edges'
);
 seq | component | node
-----+-----------+------
   1 |         1 |    1
   2 |         1 |    3
   3 |         1 |    5
   4 |         1 |    6
   5 |         1 |    7
   6 |         1 |    8
   7 |         1 |    9
   8 |         1 |   10
   9 |         1 |   11
  10 |         1 |   12
  11 |         1 |   13
  12 |         1 |   14
  13 |         1 |   15
  14 |         1 |   16
  15 |         1 |   17
  16 |         1 |   18
  17 |         2 |    2
  18 |         2 |    4
(18 rows)

在此示例中,组件 \(2`由顶点 :math:\){2, 4}` 组成,并且两个顶点也是死端结果集的一部分。

这个图需要连接起来。

Note

对于本文档的原始图,将有 3 个组件,因为该图中的交叉边是不同的组件。

为连接信息准备存储

ALTER TABLE vertices ADD COLUMN component BIGINT;
ALTER TABLE
ALTER TABLE edges ADD COLUMN component BIGINT;
ALTER TABLE

保存顶点连接信息

UPDATE vertices SET component = c.component
FROM (SELECT * FROM pgr_connectedComponents(
  'SELECT id, source, target, cost, reverse_cost FROM edges'
)) AS c
WHERE id = node;
UPDATE 18

保存边连接信息

UPDATE edges SET component = v.component
FROM (SELECT id, component FROM vertices) AS v
WHERE source = v.id;
UPDATE 20

获取最近的顶点

使用 pgr_findCloseEdges 距离组件 \(1\) 最近的顶点是顶点 \(4\)。 距离顶点 \(4\) 最近的边是 边 \(14\)

SELECT edge_id, fraction, ST_AsText(edge) AS edge, id AS closest_vertex
FROM pgr_findCloseEdges(
  $$SELECT id, geom FROM edges WHERE component = 1$$,
  (SELECT array_agg(geom) FROM vertices WHERE component = 2),
  2, partial => false) JOIN vertices USING (geom) ORDER BY distance LIMIT 1;
 edge_id | fraction |                 edge                 | closest_vertex
---------+----------+--------------------------------------+----------------
      14 |      0.5 | LINESTRING(1.999999999999 3.5,2 3.5) |              4
(1 row)

edge``可用于连接组件,利用边 :math:`14` 的``fraction 信息来分割连接边。

连接组件

连接组件有三种基本方法

  • 从顶点到边的起点

  • 从顶点到边的终点

  • 从边上的顶点到最近的顶点

    • 该解决方案需要将边缘分割。

以下查询显示了连接组件的三种方式:

WITH
info AS (
  SELECT
    edge_id, fraction, side, distance, ce.geom, edge, v.id AS closest,
    source, target, capacity, reverse_capacity, e.geom AS e_geom
  FROM pgr_findCloseEdges(
    $$SELECT id, geom FROM edges WHERE component = 1$$,
    (SELECT array_agg(geom) FROM vertices WHERE component = 2),
    2, partial => false) AS ce
  JOIN vertices AS v USING (geom)
  JOIN edges AS e ON (edge_id = e.id)
  ORDER BY distance LIMIT 1),
three_options AS (
  SELECT
    closest AS source, target, 0 AS cost, 0 AS reverse_cost,
    capacity, reverse_capacity,
    ST_X(geom) AS x1, ST_Y(geom) AS y1,
    ST_X(ST_EndPoint(e_geom)) AS x2, ST_Y(ST_EndPoint(e_geom)) AS y2,
    ST_MakeLine(geom, ST_EndPoint(e_geom)) AS geom
  FROM info
  UNION
  SELECT closest, source, 0, 0, capacity, reverse_capacity,
    ST_X(geom) AS x1, ST_Y(geom) AS y1,
    ST_X(ST_StartPoint(e_geom)) AS x2, ST_Y(ST_StartPoint(e_geom)) AS y2,
    ST_MakeLine(info.geom, ST_StartPoint(e_geom))
  FROM info
  /*
  UNION
  -- This option requires splitting the edge
  SELECT closest, NULL, 0, 0, capacity, reverse_capacity,
    ST_X(geom) AS x1, ST_Y(geom) AS y1,
    ST_X(ST_EndPoint(edge)) AS x2, ST_Y(ST_EndPoint(edge)) AS y2,
    edge
  FROM info */
  )
INSERT INTO edges
  (source, target,
    cost, reverse_cost,
    capacity, reverse_capacity,
    x1, y1, x2, y2,
    geom)
(SELECT
    source, target, cost, reverse_cost, capacity, reverse_capacity,
    x1, y1, x2, y2, geom
  FROM three_options);
INSERT 0 2

检查组件

忽略需要进一步工作的边缘。 该图现在已完全连接,因为只有一个组件。

SELECT * FROM pgr_connectedComponents(
  'SELECT id, source, target, cost, reverse_cost FROM edges'
);
 seq | component | node
-----+-----------+------
   1 |         1 |    1
   2 |         1 |    2
   3 |         1 |    3
   4 |         1 |    4
   5 |         1 |    5
   6 |         1 |    6
   7 |         1 |    7
   8 |         1 |    8
   9 |         1 |    9
  10 |         1 |   10
  11 |         1 |   11
  12 |         1 |   12
  13 |         1 |   13
  14 |         1 |   14
  15 |         1 |   15
  16 |         1 |   16
  17 |         1 |   17
  18 |         1 |   18
(18 rows)

另请参阅

索引和表格