es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

sf y networks en R: crear una lista de bordes a partir de objetos sf de linestrings y puntos distintos.

Tengo un objeto sf de nodos (stops) y otro de linestrings (rutas).


<h1>ejemplo de juguete</h1> <h2>nodos</h2> <p>p1 = st<em>point(c(7, 51)) p2 = st</em>point(c(7, 52)) p3 = st<em>point(c(7, 53)) p4 = st</em>point(c(8, 52)) nodos = st<em>as</em>sf(st_sfc(p1, p2, p3,p4, crs = 4326))</p> <h2>rutas</h2> <p>e1 = st<em>cast(st</em>union(p1,p3), "LINESTRING") e2 = st<em>cast(st</em>union(p1,p4), "LINESTRING") e3 = st<em>cast(st</em>union(p3,p4), "LINESTRING") lineas = st<em>as</em>sf(st_sfc(e1, e2, e3, crs = 4326))</p> <p>```</p> ¿Cómo obtener una lista de aristas de secciones de ruta que conecten directamente dos nodos?

Resultado deseado

from | to
p1 | p2
p2 | p3
p1 | p4
p3 | p4

“`
Aquí hay una línea entre p1 y p3, pero p2 está en el medio, por lo que hay 2 aristas entre p1-p2 y p2-p3

Sé que el paquete sfnetwork puede construir una red con linestrings o con puntos, pero ¿cómo puedo crear una red espacial con la intersección de líneas y puntos?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para obtener un lista de aristas de secciones de ruta que conectan directamente dos nodos, se puede utilizar la función st_crosses() para identificar qué rutas intersectan qué nodos, y luego extraer los puntos de inicio y fin de cada segmento de intersección utilizando las funciones st_startpoint() y st_endpoint(). Los puntos resultantes se pueden emparejar nuevamente con los nodos originales utilizando la función st_equals(). Aquí hay un ejemplo de código que extrae la lista de aristas deseada:

    library(sf)
    
    # ejemplos de nodos y rutas
    p1 = st_point(c(7, 51))
    p2 = st_point(c(7, 52))
    p3 = st_point(c(7, 53))
    p4 = st_point(c(8, 52))
    nodes = st_as_sf(st_sfc(p1, p2, p3, p4, crs = 4326))
    
    e1 = st_cast(st_union(p1, p3), "LINESTRING")
    e2 = st_cast(st_union(p1, p4), "LINESTRING")
    e3 = st_cast(st_union(p3, p4), "LINESTRING")
    lines = st_as_sf(st_sfc(e1, e2, e3, crs = 4326))
    
    # identificar segmentos de intersección
    intersects = st_crosses(lines, nodes)
    
    # extraer lista de aristas
    edgelist = st_as_sf(lapply(seq_along(intersects),
                                function(i) {
                                  line = lines[intersects[,i]]
                                  node1 = nodes[st_equals(st_startpoint(line), nodes)]
                                  node2 = nodes[st_equals(st_endpoint(line), nodes)]
                                  data.frame(from = node1$geometry, to = node2$geometry)
                                }),
                        crs = 4326,
                        agr = "constant")
    
    print(edgelist)
    #>    from to
    #> 1 POINT (7 51) POINT (7 52)
    #> 2 POINT (7 52) POINT (7 53)
    #> 3 POINT (7 51) POINT (8 52)
    #> 4 POINT (7 53) POINT (8 52)
    

    Para crear una red espacial con la intersección de líneas y puntos, se puede utilizar el paquete sfnetworks y construir la red a partir de los vértices y aristas extraídos anteriormente. Aquí hay un ejemplo de código que construye y traza la red:

    library(sfnetworks)
    
    # construir red
    net = sfnetwork(nodes = nodes, edges = edgelist)
    
    # trazar la red
    plot(net, sf_layers = "geometry")
    

    Esto trazará la red con los nodos como puntos y las aristas como líneas que los conectan.

Comments are closed.