pgr_nodeNetwork

pgr_nodeNetwork - Crea los nodos de una tabla de bordes de la red.

Autor:Nicolas Ribot
Derechos de autor:
 Nicolas Ribot, el código fuente está liberado bajo la licencia MIT-X.

La función carga los bordes de una tabla que no tiene los nodos en las intersecciones y reescribe los bordes con los nodos en una nueva tabla.

pgr_nodenetwork(edge_table, tolerance, id, text the_geom, table_ending, rows_where, outall)
RETURNS TEXT

Disponibilidad

  • Versión 2.0.0
    • Función oficial

Soporte

Descripción

Las características principales son:

Un problema común asociado con la incorporación de datos SIG en pgRouting es el hecho de que los datos a menudo no están correctamente referenciados con nodos. Esto provoca topologías no válidas, que resultan en rutas que son incorrectas.

Que los bordes estén indicados con nodos significa que, en en cada intersección de la red de caminos, los bordes se descompondrán en segmentos separados del camino. Los casos como una intersección de puente o túnel donde no existe conexión vial no son detectados por esta función.

Esta función lee la tabla table_in, que tiene una columna de clave principal gid_cname y columna de la geometría llamada geo_cname, y verifica la intersección de todos los segmentos contra todos los demás segmentos creando una tabla de salida table_out. Usa la tolerancia tolerance para decidir cuáles nodos son considerados como mismo nodo.

Parámetros

edge_table:text La tabla de la red. (puede contener el nombre del esquema)
tolerancia:float8 tolerancia para puntos de coincidencia (en la unidad de proyección)
id:text``Nombre de la columna de la clave principal de la tabla de red. Valor por defecto es ``id”.
the_geom:text nombre de la columna de la geometría en la tabla de la red. El valor por defecto es the_geom`
table_ending:text sufijo para la nueva tabla. El valor predeterminado es noded.

La tabla de salida tendrá para edge_table_noded

id:bigint identificador del vértice.
old_id:bigint identificador del borde en la tabla original
sub_id:integer número del segmento del borde original
source:integer Columna de origen vacía que se utilizará con la función pgr_createTopology
target:integer Columna vacía de destinoque se utilizará con la función pgr_createTopology
la geom:geometry Columna de geometría de la red discontínua

Ejemplos

Vamos a crear la topología para los datos en Datos Muestra

SELECT pgr_createTopology('edge_table', 0.001, clean := TRUE);
NOTICE:  PROCESSING:
NOTICE:  pgr_createTopology('edge_table', 0.001, 'the_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.edge_table is: public.edge_table_vertices_pgr
NOTICE:  ----------------------------------------------
 pgr_createtopology
--------------------
 OK
(1 row)

Ahora podemos analizar la red.

SELECT pgr_analyzegraph('edge_table', 0.001);
NOTICE:  PROCESSING:
NOTICE:  pgr_analyzeGraph('edge_table',0.001,'the_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)

El análisis dice que la red tiene un hueco y una intersección. Trataremos de solucionar el problema usando:

SELECT pgr_nodeNetwork('edge_table', 0.001);
NOTICE:  PROCESSING:
NOTICE:  id: id
NOTICE:  the_geom: the_geom
NOTICE:  table_ending: noded
NOTICE:  rows_where:
NOTICE:  outall: f
NOTICE:  pgr_nodeNetwork('edge_table', 0.001, 'id', 'the_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.edge_table_noded
NOTICE:  ----------------------------------
 pgr_nodenetwork
-----------------
 OK
(1 row)

Inspeccionar la tabla generada, podemos ver que los bordes 13,14 y 18 ha sido segmentado

SELECT old_id, sub_id FROM edge_table_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)

Podemos crear la topología de la nueva red

SELECT pgr_createTopology('edge_table_noded', 0.001);
NOTICE:  PROCESSING:
NOTICE:  pgr_createTopology('edge_table_noded', 0.001, 'the_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.edge_table_noded is: public.edge_table_noded_vertices_pgr
NOTICE:  ----------------------------------------------
 pgr_createtopology
--------------------
 OK
(1 row)

Ahora analicemos la nueva topología

SELECT pgr_analyzegraph('edge_table_noded', 0.001);
NOTICE:  PROCESSING:
NOTICE:  pgr_analyzeGraph('edge_table_noded',0.001,'the_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)

Imágenes

Imágen del Antes

before image

Imágen del Después

after image

Comparando los resultados

Comparando con el análisis del edge_table original, vemos que:

  Antes de Después de
Nombre de la tabla edge_table edge_table_noded
Campos Todos los campos originales Tiene solamente campos básicos para hacer un análisis de topología
Callejones sin salida
  • Los bordes con 1 callejón sin salida: 1,6,24
  • Bordes con 2 callejones sin salida 17,18

Nodo derecho borde de 17 es un callejón sin salida porque no hay ningún otro borde que comparta ese mismo nodo. (cnt = 1)

Los bordes con 1 callejón sin salida: 1-1, 6-1,14-2, 18-1-17-1 18-2
Segmentos aislados dos aislados segmentos: 17 y 18 ambos tienen 2 callejones sin salida
Segmentos no aislados
  • Borde 17 ahora comparte un nodo con bordes 14-1 y 14-2
  • Bordes 18-1 y 18-2 compartir un nodo con bordes 13-1 y 13-2
Espacios Existe un espacio entre 17 y 14 borde borde 14 es cerca del nodo derecho del borde 17 Borde 14 fue segmentado ahora bordes: 14-1 14-2 17 comparten el mismo nodo, el valor de tolerancia fue tomado en cuenta
Intersecciones Bordes 13 y 18 años se intersectan Bordes fueron segmentados, ahora en el punto de la interesección hay un nodo y los bordes siguientes lo comparten: 13-1 13-2-18-1 18-2

Ahora, vamos a incluir los segmentos 13-1, 13-2-14-1, 14-2, 18-1 y 18-2 en nuestra tabla de bordes, copiando además los datos para dir, costo y costo inverso con los siguientes los pasos:

  • Agregar una columna old_id en edge_table, esta columna va a seguir la pista el id del borde original
  • Introduzca sólo los bordes segmentados, es decir, aquellos cuyo max(sub_id) > 1
alter table edge_table drop column if exists old_id;
NOTICE:  column "old_id" of relation "edge_table" does not exist, skipping
ALTER TABLE
alter table edge_table add column old_id integer;
ALTER TABLE
insert into edge_table (old_id, dir, cost, reverse_cost, the_geom)
   (with
       segmented as (select old_id,count(*) as i from edge_table_noded group by old_id)
   select  segments.old_id, dir, cost, reverse_cost, segments.the_geom
       from edge_table as edges join edge_table_noded as segments on (edges.id = segments.old_id)
       where edges.id in (select old_id from segmented where i>1) );
INSERT 0 6

Recreamos la topología:

SELECT pgr_createTopology('edge_table', 0.001);
NOTICE:  PROCESSING:
NOTICE:  pgr_createTopology('edge_table', 0.001, 'the_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.edge_table is: public.edge_table_vertices_pgr
NOTICE:  ----------------------------------------------
 pgr_createtopology
--------------------
 OK
(1 row)

Para obtener los mismos resultados de análisis que la topología de edge_table_noded, hacemos la siguiente consulta:

SELECT pgr_analyzegraph('edge_table', 0.001, rows_where:='id not in (select old_id from edge_table where old_id is not null)');
NOTICE:  PROCESSING:
NOTICE:  pgr_analyzeGraph('edge_table',0.001,'the_geom','id','source','target','id not in (select old_id from edge_table 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)

Para obtener los mismos resultados de análisis como el edge_table original, hacemos la siguiente consulta:

SELECT pgr_analyzegraph('edge_table', 0.001, rows_where:='old_id is null');
NOTICE:  PROCESSING:
NOTICE:  pgr_analyzeGraph('edge_table',0.001,'the_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)

O podemos analizar todo porque, tal vez edge 18 es un puente, borde 14 es un bajo paso y también hay una juntura nivel calle, y lo mismo ocurre con los bordes 17 y 13.

SELECT pgr_analyzegraph('edge_table', 0.001);
NOTICE:  PROCESSING:
NOTICE:  pgr_analyzeGraph('edge_table',0.001,'the_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)

Ver también

Topología - Familia de Funciones para obtener una visión general de una topología para algoritmos de enrutamiento. pgr_analyzeOneWay para analizar la direccionalidad de los bordes. pgr_createTopology para crear una topología basada en la geometría. pgr_analyzeGraph para analizar los bordes y vértices de la tabla de bordes.

Índices y tablas