pgr_nodeNetwork

pgr_nodeNetwork - Crea los nodos de una tabla de aristas 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, [options])
| options: [id, text the_geom, table_ending, rows_where, outall]

| RETURNS TEXT

Disponibilidad

  • Versión 2.0.0

    • Función oficial

Descripción

Las principales características 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 como anudados significa que, en cada intersección de la red de caminos, las aristas se descompondrán en segmentos separados . Los casos como una intersección por puente o túnel donde no existe conexión vial no son detectados por esta función.

Esta función lee la tabla edge_table, que tiene una columna de clave principal id y columna de la geometría llamada the_geom, y verifica la intersección de todos los segmentos contra todos los demás segmentos creando una tabla de salida edge_table_noded. 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 que tendrá para edge_table_noded

id:

bigint identificador único 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 destino que 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('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)

Ahora podemos analizar la red.

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)

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

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)

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

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)

Podemos crear la topología de la nueva red

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)

Ahora analicemos la nueva topología

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)

Imágenes

Imágen del Antes

Imágen del antes

Imágen del Después

Imágen del después

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 la arista 17 y la 14 porque la arista 14 está cerca del nodo derecho a la arista 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 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

Recreamos la topología:

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)

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

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)

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

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)

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('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)

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