Identificar las intersecciones de carreteras utilizando PostGIS

17

Estoy tratando de identificar dónde se intersecan las carreteras, y para hacer un punto en esta intersección, con el número de carreteras que forman la intersección en la lista.

Mepreguntabasihabíaalgunamaneradeusar ST_NumPoints para lograr esto, pero puedo No entiendo muy bien lo que debería estar haciendo. Lo que he hecho es crear una tabla de puntos donde las líneas se intersecan usando el siguiente código:

CREATE TABLE test_points as
SELECT      
    ST_Intersection(a.geom, b.geom),
    a.gid
FROM
    roads as a,
    roads as b
WHERE
    ST_Touches(a.geom, b.geom);

Si ejecuto esto en una muestra de carreteras, obtengo la siguiente cuadrícula de puntos (las carreteras se muestran como ilustración):

Siinspeccionounodelospuntos,veoquehaymuchospuntosapiladosunoencimadelotro:

El GID aquí es el ID de la carretera, pero no entiendo por qué hay muchos puntos. Puedo entender que se cuentan 4 puntos para una intersección de la carretera central, pero hay 12 puntos enumerados aquí. ¿Hay una mejor manera de realizar este cálculo en PostGIS?

    
pregunta djq 24.02.2012 - 22:53

3 respuestas

21

Si agrupas, solo obtendrás puntos únicos.

CREATE TABLE test_points as
SELECT      
    ST_Intersection(a.geom, b.geom),
    Count(Distinct a.gid)
FROM
    roads as a,
    roads as b
WHERE
    ST_Touches(a.geom, b.geom)
    AND a.gid != b.gid
GROUP BY
    ST_Intersection(a.geom, b.geom)
;
    
respondido por el underdark 25.02.2012 - 00:11
6

Esto es un poco más complicado de lo que podrías esperar. Eso es porque no hay una buena manera de analizar las relaciones para más de pares. No puedes poner tres líneas en una función y preguntar si todas se intersecan.

Pero, al menos un enfoque podría ser primero encontrar los cruces, luego verificar cuántas carreteras están tocando en cada cruce (todo se puede hacer en la misma consulta).

Si sus carreteras se conectan perfectamente entre sí y no hay carreteras que pasen por un cruce, entonces podría hacer algo como esto (no probado):
editado con cláusula de grupo olvidada aún no probado):

SELECT distinct_crosspoints.geom as crossing, array_agg(roads.gid), count(*) FROM
  (SELECT DISTINCT (geom) geom FROM 
    (SELECT ST_Intersection(a.geom, b.geom) geom 
     FROM roads a, roads b 
     WHERE ST_Intersects(a.geom, b.geom)
    ) all_crosspoints
   ) distinct_crosspoints
   ,roads 
 WHERE ST_Intersects(distinct_crosspoints.geom, roads.geom)
 GROUP BY distinct_crosspoints.geom;

Si las carreteras no están conectadas correctamente y / o algunas carreteras pasan por un cruce, es más complicado.

HTH

Nicklas

    
respondido por el Nicklas Avén 25.02.2012 - 21:14
1
 CREATE TABLE test_points as
    SELECT      
        ST_Intersection(a.geom, b.geom),
        Count(Distinct a.gid)
    FROM
        roads as a,
        roads as b
    WHERE
        ST_Touches(a.geom, b.geom)
        AND a.gid < b.gid   /* !!! Changed "!=" for "<"  */
    GROUP BY
        ST_Intersection(a.geom, b.geom)
    ;

Si la línea A (id 1) cruza la línea B (id 2) es un punto de intersección que necesitamos. Pero la línea B también cruza la línea A en el mismo punto. Pero no necesitamos este punto dos veces. Es por eso que estoy usando a.gid < b.gid en lugar de a.gid != b.gid

    
respondido por el Alex Os 17.06.2015 - 16:30

Lea otras preguntas en las etiquetas