Le package R: sf pointe vers plusieurs lignes avec st_cast


8

Je veux créer plusieurs lignes à partir de points donnés en tant que sf objects.

Si j'ai un certain nombre de points

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

et j'utilise st_castpour en créer des lignes

lines <- st_cast(pts, "MULTILINESTRING")

J'en obtiendrai toujours un sf objectavec plusieurs segments, mais ce que je veux obtenir, c'est plusieurs lignes (deux dans cet exemple).


Quel résultat aimeriez-vous obtenir? Avec trois points A, B et C, vous pouvez faire 3 lignes différentes: AB, AC, BC. Et si votre matrice a cent lignes?
user30184

Il semble que vous souhaitiez l'équivalent sf de cette procédure postgis - gis.stackexchange.com/questions/174472/… , ce que l'AFAIK n'est pas possible ... pour le moment. Peut-être soulever un problème sur la page github de sf?
obrl_soil

Réponses:


7

Je pense que le sfpackage doit d'abord savoir comment vous voulez créer les lignes à partir de vos points. Je veux dire quelle paire de POINTfaire chaque LINESTRING. Dans mon exemple, cela a été défini à l'intérieur de la lapplyfonction. Suivez le code reproductible et commenté ci-dessous, j'espère que cela vous aidera:

# 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)

Fig. 1


Merci Guzmán pour ta réponse! Cette solution fonctionne si l'ordre des points donnés est le même que l'ordre des lignes à créer. Mais s'il y a un autre ordre dans le sf object(comme matrix(c(10, 10, 30, 30, 15, 20), nrow = 3, byrow = TRUE)), il crée une ligne qui relie le coin inférieur gauche au point supérieur droit dans ce cas. user30184 l'a mentionné dans son commentaire ci-dessus. Y a-t-il une possibilité de trier les points par distance minimale ou quelque chose comme ça? Merci!
danceb

4

J'ai trouvé une solution! Pour tous les autres, qui cherchent également une réponse, la façon dont je l'ai résolu:

# 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)

entrez la description de l'image ici

Néanmoins, merci encore pour votre aide!

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.