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]
| RETURNSTEXT
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 esnoded
.
La tabla de salida 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 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 |
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 |
|
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