O pacote R: sf aponta para várias linhas com st_cast


8

Eu quero criar várias linhas a partir de pontos determinados como sf objects.

Se eu tiver vários pontos como

library(sf)
pts <- st_multipoint(matrix(c(10, 10, 15, 20, 30, 30), nrow = 3, byrow = TRUE), dim = "XY")

e eu estou usando st_castpara criar linhas deles

lines <- st_cast(pts, "MULTILINESTRING")

Sempre receberei um sf objectcom vários segmentos, mas o que quero obter é várias linhas (duas neste exemplo).


Que resultado você gostaria de obter? Com três pontos A, B e C, você pode fazer 3 linhas diferentes: AB, AC, BC. E se sua matriz tiver cem linhas?
User30184

Parece que você deseja o equivalente sf deste procedimento postgis - gis.stackexchange.com/questions/174472/… , que o AFAIK ainda não é possível ... ainda. Talvez levantar um problema na página do sith no github?
obrl_soil

Respostas:


7

Eu acho que o sfpacote precisa saber primeiro como você deseja criar as linhas a partir dos seus pontos. Quero dizer que par de POINTfazer cada LINESTRING. No meu exemplo que foi definido dentro da lapplyfunção. Siga o código reproduzível e comentado abaixo, espero que ajude:

# Load library
library(sf)

# Create points data
multipoints <- st_multipoint(matrix(c(10, 10, 15, 20, 30, 30), nrow = 3, byrow = TRUE), dim = "XY")
points <- st_cast(st_geometry(multipoints), "POINT") 

# Number of total linestrings to be created
n <- length(points) - 1

# Build linestrings
linestrings <- lapply(X = 1:n, FUN = function(x) {

  pair <- st_combine(c(points[x], points[x + 1]))
  line <- st_cast(pair, "LINESTRING")
  return(line)

})

# One MULTILINESTRING object with all the LINESTRINGS
multilinetring <- st_multilinestring(do.call("rbind", linestrings))

# Plot
plot(multipoints, pch = 19, cex = 2)
plot(multilinetring[[1]], col = "orange", lwd = 2, add = TRUE)
plot(multilinetring[[2]], col = "green", lwd = 2, add = TRUE)

Figura 1


Obrigado Guzmán pela sua resposta! Esta solução funciona se a ordem dos pontos indicados for a mesma que a das linhas a serem criadas. Mas se houver outra ordem no sf object(like matrix(c(10, 10, 30, 30, 15, 20), nrow = 3, byrow = TRUE)), cria uma linha que liga a parte inferior esquerda com o ponto superior direito neste caso. user30184 mencionou isso em seu comentário acima. Existe a possibilidade de classificar os pontos por distância mínima ou algo assim? Obrigado!
91818 danceb

4

Eu encontrei uma solução! Para todos os outros, que também procuram uma resposta, da maneira que resolvi:

# Load library
library(sf)

# create points data
m <- matrix(c(10, 10, 30, 30, 15, 20), nrow = 3, byrow = TRUE)
multipoints <- st_multipoint(m, dim = "XY")

# save ranges of coordinates
x.range <- max(m[,1]) - min(m[,1])
y.range <- max(m[,2]) - min(m[,2])

# order by greatest range
if (x.range > y.range) {
  sort.id <- order(m[,1])
} else if (y.range > x.range) {
  sort.id <- order(m[,2])
} else if (y.range == x.range) {
  sort.id <- order(m[,2])
}

# creat lines by previous sorting and save them in the list
lines <- lapply(1:(length(sort.id)-1), function(i) {
  st_linestring(rbind(multipoints[sort.id[i],], multipoints[sort.id[i+1],]))
})

# plot results
plot(multipoints)
plot(lines[[1]], col = "orange", lwd = 2, add = TRUE)
plot(lines[[2]], col = "green", lwd = 2, add = TRUE)

insira a descrição da imagem aqui

No entanto, obrigado novamente por sua ajuda!

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.