pgr_nodeNetwork¶
Nombre¶
pgr_nodeNetwork - Crea los nodos de una tabla de bordes de la red.
Author: | Nicolas Ribot |
---|---|
Copyright: | Nicolas Ribot, el código fuente está liberado bajo la licencia MIT-X. |
Sinopsis¶
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.
text pgr_nodenetwork(text edge_table, float8, tolerance,
text id='id', text the_geom='the_geom',text table_ending='noded')
Descripción¶
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) |
---|---|
tolerance: | 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 vacía para utilizarse con la función pgr_createTopology |
target: | integer Columna vacía para el destino. Para utilizarse con la función pgr_createTopology |
the geom: | geometry Columna de geometría de la red discontínua |
Historia
- Nuevo en la versión 2.0.0
Ejemplo¶
Vamos a crear la topología de los datos Datos Muestra
SELECT pgr_createTopology('edge_table', 0.001);
NOTICE: PROCESSING:
NOTICE: pgr_createTopology('edge_table',0.001,'the_geom','id','source','target','true')
NOTICE: Performing checks, pelase 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, pelase 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 nos dice que la red tiene un espacio y una intersección. Tratamos de arreglar el problema usando:
SELECT pgr_nodeNetwork('edge_table', 0.001);
NOTICE: PROCESSING:
NOTICE: pgr_nodeNetwork('edge_table',0.001,'the_geom','id','noded')
NOTICE: Performing checks, pelase wait .....
NOTICE: Processing, pelase wait .....
NOTICE: Splitted 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','true')
NOTICE: Performing checks, pelase 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, pelase 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_createtopology
--------------------
OK
(1 row)
Imágenes¶
Before Image |
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 |
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 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;
alter table edge_table add column old_id integer;
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) );
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','true')
NOTICE: Performing checks, pelase wait .....
NOTICE: Creating Topology, Please wait...
NOTICE: -------------> TOPOLOGY CREATED FOR 24 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, pelase 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_createtopology
--------------------
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, pelase 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_createtopology
--------------------
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, pelase 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_createtopology
--------------------
OK
(1 row)
Véase también¶
Topología para Ruteo para tener una visión general de una topología de algoritmos de encaminamiento. pgr_analyzeOneway para analizar la direccionalidad de los bordes. pgr_createTopology para crear una topología basado en la geometría. pgr_analyzeGraph para analizar los bordes y los nodos de la tabla del borde.