R: sf-Paket zeigt mit st_cast auf mehrere Zeilen

8

Ich möchte mehrere Linien aus bestimmten Punkten als erstellen sf objects.

Wenn ich eine Reihe von Punkten als habe

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

und ich benutze st_cast, um Linien von ihnen zu erstellen

lines <- st_cast(pts, "MULTILINESTRING")

Ich werde immer eine sf objectmit mehreren Segmenten bekommen, aber was ich bekommen möchte, sind mehrere Zeilen (zwei in diesem Beispiel).

danceb
quelle
Welches Ergebnis möchten Sie erzielen? Mit drei Punkten A, B und C können Sie drei verschiedene Linien erstellen: AB, AC, BC. Was ist, wenn Ihre Matrix hundert Zeilen enthält?
user30184
Es hört sich so an, als ob Sie das SF-Äquivalent dieser Postgis-Prozedur wollen - gis.stackexchange.com/questions/174472/… , was AFAIK noch nicht möglich ist. Vielleicht ein Problem auf der Github-Seite von sf ansprechen?
obrl_soil

Antworten:

7

Ich denke, dass das sfPaket zuerst wissen muss, wie Sie die Linien aus Ihren Punkten erstellen möchten. Ich meine, welches Paar POINTmacht jeden LINESTRING. In meinem Beispiel wurde das innerhalb der lapplyFunktion definiert . Folgen Sie dem reproduzierbaren und kommentierten Code unten, hoffentlich hilft das:

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

fig1

Guzmán
quelle
Danke Guzmán für deine Antwort! Diese Lösung funktioniert, wenn die Reihenfolge der angegebenen Punkte mit der Reihenfolge der zu erstellenden Linien übereinstimmt. Wenn es jedoch eine andere Reihenfolge im sf object( Gefällt mir matrix(c(10, 10, 30, 30, 15, 20), nrow = 3, byrow = TRUE)) gibt, wird eine Linie erstellt, die in diesem Fall den unteren linken mit dem oberen rechten Punkt verbindet. user30184 hat dies in seinem obigen Kommentar erwähnt. Gibt es eine Möglichkeit, die Punkte nach minimalem Abstand oder ähnlichem zu sortieren? Vielen Dank!
Danceb
4

Ich habe eine Lösung gefunden! Für alle anderen, die ebenfalls nach einer Antwort suchen, wie ich sie gelöst habe:

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

Geben Sie hier die Bildbeschreibung ein

Trotzdem nochmals vielen Dank für Ihre Hilfe!

danceb
quelle