pgr_nodeNetwork

pgr_nodeNetwork - 网络边表的节点。

作者:

Nicolas Ribot

版权:

Nicolas Ribot,源代码根据 MIT-X 许可证发布。

该函数从非"noded"网络表中读取边,并将"noded"边写入新表中。

| pgr_nodenetwork(edge_table, tolerance, [options])
| options: [id, text the_geom, table_ending, rows_where, outall]

| RETURNS TEXT

可用性

  • 版本2.0.0

    • 官方 函数

描述

主要特点是:

将 GIS 数据引入 pgRouting 的一个常见问题是数据通常没有正确“节点化”。 这将创建无效的拓扑,从而导致路由不正确。

我们所说的 "noded"是指在道路网络的每个交叉口,所有边缘都将被分成单独的路段。 在某些情况下,例如天桥和地下通道交叉口,您无法从天桥穿越到地下通道,但此功能无法检测和适应这些情况。

该函数读取 edge_table``表,该表具有主键列 ``id 和名为``the_geom`` 的几何列,并将其中的所有段与所有其他段相交,然后创建表 edge_table_noded。 它使用``tolerance`` 来决定容差内的多个节点被视为同一节点。

参数

edge_table:

text 网络表的名称(可能包含模式名称)

tolerance:

float8 重合点公差(以投影单位表示)dd

id:

text 网络表的主键列名称。 默认值为``id``。

the_geom:

text``网络表的几何列名称。 默认值为``the_geom

table_ending:

text``新表的后缀。 默认值是``noded

输出表中将包含 edge_table_noded 内容

id:

bigint 表的唯一标识符

old_id:

bigint Identifier of the edge in original table

sub_id:

integer 原边的段号

source:

integerpgr_createTopology 函数一起使用的空source列

target:

integerpgr_createTopology 函数一起使用的空target列

the geom:

geometry 节点网络的几何列

示例

让我们为 示例数据 中的数据创建拓扑

SELECT pgr_createTopology('edges', 0.001, 'geom', clean := TRUE);
NOTICE:  PROCESSING:
NOTICE:  pgr_createTopology('edges', 0.001, 'geom', 'id', 'source', 'target', rows_where := 'true', clean := t)
NOTICE:  Performing checks, please wait .....
NOTICE:  Creating Topology, Please wait...
NOTICE:  -------------> TOPOLOGY CREATED FOR  18 edges
NOTICE:  Rows with NULL geometry or NULL id: 0
NOTICE:  Vertices table for table public.edges is: public.edges_vertices_pgr
NOTICE:  ----------------------------------------------
 pgr_createtopology
--------------------
 OK
(1 row)

现在我们可以分析网络了。

SELECT pgr_analyzegraph('edges', 0.001, 'geom');
NOTICE:  PROCESSING:
NOTICE:  pgr_analyzeGraph('edges',0.001,'geom','id','source','target','true')
NOTICE:  Performing checks, please wait ...
NOTICE:  Analyzing for dead ends. Please wait...
NOTICE:  Analyzing for gaps. Please wait...
NOTICE:  Analyzing for isolated edges. Please wait...
NOTICE:  Analyzing for ring geometries. Please wait...
NOTICE:  Analyzing for intersections. Please wait...
NOTICE:              ANALYSIS RESULTS FOR SELECTED EDGES:
NOTICE:                    Isolated segments: 2
NOTICE:                            Dead ends: 7
NOTICE:  Potential gaps found near dead ends: 1
NOTICE:               Intersections detected: 1
NOTICE:                      Ring geometries: 0
 pgr_analyzegraph
------------------
 OK
(1 row)

分析告诉我们,网络存在缺口和交叉点。 我们尝试使用以下方法解决该问题:

SELECT pgr_nodeNetwork('edges', 0.001, the_geom => 'geom');
NOTICE:  PROCESSING:
NOTICE:  id: id
NOTICE:  the_geom: geom
NOTICE:  table_ending: noded
NOTICE:  rows_where:
NOTICE:  outall: f
NOTICE:  pgr_nodeNetwork('edges', 0.001, 'id', 'geom', 'noded', '',  f)
NOTICE:  Performing checks, please wait .....
NOTICE:  Processing, please wait .....
NOTICE:    Split Edges: 3
NOTICE:   Untouched Edges: 15
NOTICE:       Total original Edges: 18
NOTICE:   Edges generated: 6
NOTICE:   Untouched Edges: 15
NOTICE:         Total New segments: 21
NOTICE:   New Table: public.edges_noded
NOTICE:  ----------------------------------
 pgr_nodenetwork
-----------------
 OK
(1 row)

检查生成的表,我们可以看到边 13,14 和 18 已被分段

SELECT old_id, sub_id FROM edges_noded ORDER BY old_id, sub_id;
 old_id | sub_id
--------+--------
      1 |      1
      2 |      1
      3 |      1
      4 |      1
      5 |      1
      6 |      1
      7 |      1
      8 |      1
      9 |      1
     10 |      1
     11 |      1
     12 |      1
     13 |      1
     13 |      2
     14 |      1
     14 |      2
     15 |      1
     16 |      1
     17 |      1
     18 |      1
     18 |      2
(21 rows)

我们可以创建新网络的拓扑

SELECT pgr_createTopology('edges_noded', 0.001, 'geom');
NOTICE:  PROCESSING:
NOTICE:  pgr_createTopology('edges_noded', 0.001, 'geom', 'id', 'source', 'target', rows_where := 'true', clean := f)
NOTICE:  Performing checks, please wait .....
NOTICE:  Creating Topology, Please wait...
NOTICE:  -------------> TOPOLOGY CREATED FOR  21 edges
NOTICE:  Rows with NULL geometry or NULL id: 0
NOTICE:  Vertices table for table public.edges_noded is: public.edges_noded_vertices_pgr
NOTICE:  ----------------------------------------------
 pgr_createtopology
--------------------
 OK
(1 row)

现在我们来分析一下新的拓扑

SELECT pgr_analyzegraph('edges_noded', 0.001, 'geom');
NOTICE:  PROCESSING:
NOTICE:  pgr_analyzeGraph('edges_noded',0.001,'geom','id','source','target','true')
NOTICE:  Performing checks, please wait ...
NOTICE:  Analyzing for dead ends. Please wait...
NOTICE:  Analyzing for gaps. Please wait...
NOTICE:  Analyzing for isolated edges. Please wait...
NOTICE:  Analyzing for ring geometries. Please wait...
NOTICE:  Analyzing for intersections. Please wait...
NOTICE:              ANALYSIS RESULTS FOR SELECTED EDGES:
NOTICE:                    Isolated segments: 0
NOTICE:                            Dead ends: 6
NOTICE:  Potential gaps found near dead ends: 0
NOTICE:               Intersections detected: 0
NOTICE:                      Ring geometries: 0
 pgr_analyzegraph
------------------
 OK
(1 row)

图片

之前的图像

图片前

后面的图像

图像后

比较结果

与原始edge_table中的分析相比,我们看到了这一点。

表名

edge_table

edge_table_noded

字段

所有原始字段

仅具有进行拓扑分析的基本字段

死端

  • 有 1 个死端的边:1、6、24

  • Edges with 2 dead ends: 17,18

边 17 的右侧节点是一个死端,因为没有其他边共享同一节点。 (cnt=1)

有 1 个死端的边:1-1 ,6-1,14-2, 18-1 17-1 18-2

孤立的片段

two isolated segments: 17 and 18 both they have 2 dead ends

无孤立段
  • 边 17 现在与边 14-1 和 14-2 共享一个节点

  • 边 18-1 和 18-2 与边 13-1 和 13-2 共享一个节点

差距

边 17 和边 14 之间有间隙,因为边 14 靠近边 17 的右侧节点

边缘14 被分段了,现在边缘14-1、14-2 和 17 共享同一个节点。容差值已被考虑

交叉口

边 13 和 18 相交

边被分段,所以,现在在交点处有一个节点,并且以下边共享它: 13-1 13-2 18-1 18-2

现在,我们将包括段 13-1、13-2、14-1、14-2、18-1 和 18-2 到我们的边表中,并复制 dir、cost 和 reverse cost 的数据,按照以下步骤进行:

  • 在边表中添加一列old_id,该列将跟踪原始边的id

  • 仅插入分段边,即 max(sub_id) >1 的边

alter table edges drop column if exists old_id;
NOTICE:  column "old_id" of relation "edges" does not exist, skipping
ALTER TABLE
alter table edges add column old_id integer;
ALTER TABLE
insert into edges (old_id, cost, reverse_cost, geom)
   (with
       segmented as (select old_id,count(*) as i from edges_noded group by old_id)
   select  segments.old_id, cost, reverse_cost, segments.geom
       from edges as edges join edges_noded as segments on (edges.id = segments.old_id)
       where edges.id in (select old_id from segmented where i>1) );
INSERT 0 6

我们重新创建拓扑:

SELECT pgr_createTopology('edges', 0.001, 'geom');
NOTICE:  PROCESSING:
NOTICE:  pgr_createTopology('edges', 0.001, 'geom', 'id', 'source', 'target', rows_where := 'true', clean := f)
NOTICE:  Performing checks, please wait .....
NOTICE:  Creating Topology, Please wait...
NOTICE:  -------------> TOPOLOGY CREATED FOR  6 edges
NOTICE:  Rows with NULL geometry or NULL id: 0
NOTICE:  Vertices table for table public.edges is: public.edges_vertices_pgr
NOTICE:  ----------------------------------------------
 pgr_createtopology
--------------------
 OK
(1 row)

为了获得与edge_table_noded的拓扑相同的分析结果,我们执行以下查询:

SELECT pgr_analyzegraph('edges', 0.001, 'geom', rows_where:='id not in (select old_id from edges where old_id is not null)');
NOTICE:  PROCESSING:
NOTICE:  pgr_analyzeGraph('edges',0.001,'geom','id','source','target','id not in (select old_id from edges where old_id is not null)')
NOTICE:  Performing checks, please wait ...
NOTICE:  Analyzing for dead ends. Please wait...
NOTICE:  Analyzing for gaps. Please wait...
NOTICE:  Analyzing for isolated edges. Please wait...
NOTICE:  Analyzing for ring geometries. Please wait...
NOTICE:  Analyzing for intersections. Please wait...
NOTICE:              ANALYSIS RESULTS FOR SELECTED EDGES:
NOTICE:                    Isolated segments: 0
NOTICE:                            Dead ends: 6
NOTICE:  Potential gaps found near dead ends: 0
NOTICE:               Intersections detected: 0
NOTICE:                      Ring geometries: 0
 pgr_analyzegraph
------------------
 OK
(1 row)

为了获得与原始edge_table相同的分析结果,我们执行以下查询:

SELECT pgr_analyzegraph('edges', 0.001, 'geom', rows_where:='old_id is null');
NOTICE:  PROCESSING:
NOTICE:  pgr_analyzeGraph('edges',0.001,'geom','id','source','target','old_id is null')
NOTICE:  Performing checks, please wait ...
NOTICE:  Analyzing for dead ends. Please wait...
NOTICE:  Analyzing for gaps. Please wait...
NOTICE:  Analyzing for isolated edges. Please wait...
NOTICE:  Analyzing for ring geometries. Please wait...
NOTICE:  Analyzing for intersections. Please wait...
NOTICE:              ANALYSIS RESULTS FOR SELECTED EDGES:
NOTICE:                    Isolated segments: 2
NOTICE:                            Dead ends: 7
NOTICE:  Potential gaps found near dead ends: 1
NOTICE:               Intersections detected: 1
NOTICE:                      Ring geometries: 0
 pgr_analyzegraph
------------------
 OK
(1 row)

或者我们可以分析所有内容,因为也许边 18 是立交桥,边 14 是地下通道,还有一个街道水平交汇处,边 17 和 13 也会发生同样的情况。

SELECT pgr_analyzegraph('edges', 0.001, 'geom');
NOTICE:  PROCESSING:
NOTICE:  pgr_analyzeGraph('edges',0.001,'geom','id','source','target','true')
NOTICE:  Performing checks, please wait ...
NOTICE:  Analyzing for dead ends. Please wait...
NOTICE:  Analyzing for gaps. Please wait...
NOTICE:  Analyzing for isolated edges. Please wait...
NOTICE:  Analyzing for ring geometries. Please wait...
NOTICE:  Analyzing for intersections. Please wait...
NOTICE:              ANALYSIS RESULTS FOR SELECTED EDGES:
NOTICE:                    Isolated segments: 0
NOTICE:                            Dead ends: 3
NOTICE:  Potential gaps found near dead ends: 0
NOTICE:               Intersections detected: 5
NOTICE:                      Ring geometries: 0
 pgr_analyzegraph
------------------
 OK
(1 row)

另请参阅

Topology - 函数族 用于概述路由算法的拓扑。 pgr_analyzeOneWay 分析边方向性的方法。 pgr_createTopology 根据几何图创建拓扑。 pgr_analyzeGraph 分析边表的边和顶点。

索引和表格