Comment créer efficacement des Linestrings à partir de points?
J'ai geom POINTs dans deux cadres de données séparés. Ce que je veux faire est de connecter des points avec une ligne (plus tard sur une carte), c'est pourquoi je veux créer Linestring pour chaque paire de points à partir de ces blocs de données. Je l'ai fait comme ça:
coordsCust <- table %>%
st_as_sf(coords = c("lonCust","latCust"), crs = 4326)
coordsApp <- table %>%
st_as_sf(coords = c("lonApp","latApp"), crs = 4326) %>%
st_geometry()
et Linestring:
lines <- st_sfc(mapply(function(a,b){
st_cast(st_union(a,b),"LINESTRING")},
coordsCust$geometry, coordsApp$geometry, SIMPLIFY=FALSE))
Ce code fonctionne, je peux créer des Linestrings pour chaque paire de points, ligne par ligne:
LINESTRING (14.035 51.65182, 14.33418 53.53346)
LINESTRING (20.42767 49.98073, 16.62978 52.31037)
LINESTRING (20.18762 50.03337, 16.62978 52.31037)
LINESTRING (19.04625 49.79234, 16.62978 52.31037)
LINESTRING (21.35808 50.92382, 16.62978 52.31037)
Le problème est que pour 30 000 lignes, cette solution fonctionne très lentement - environ 21 secondes. Existe-t-il un autre moyen de créer des linestrings à partir de points? Quelque chose qui fonctionne beaucoup plus vite? J'ai cherché des solutions sur le web mais en vain. J'ai lu quelque chose sur la conversion de sf en matrice et son utilisation, pmap
mais je ne sais pas comment l'implémenter ici.
MISE À JOUR: si je veux utiliser la fonction sfheaders :: sf_linestring, je dois joindre les géométries des deux ensembles de données. Je fais ça comme ça:
df <- cbind(coordsCust,coordsApp)
et la trame de données finale (j'en ai montré la partie la plus importante) est présentée ci-dessous:

Malheureusement, sf_linestring ne fonctionne pas correctement sur cette trame de données. J'ai besoin de créer une ligne entre les POINTS pour chaque ligne séparément, comme indiqué à l'écran.
Réponses
Sans un exemple d'ensemble de données, il est difficile de répondre complètement à votre question. Mais si vous pouvez obtenir votre data.frame sous forme `` longue '', vous sfheaders
pouvez le faire en un instant
n <- 30000
df <- data.frame(
x = rnorm(n)
, y = rnorm(n)
)
df$id <- rep(1:(n/2), each = 2)
sfheaders::sf_linestring(
obj = df
, x = "x"
, y = "y"
, linestring_id = "id"
)
# Simple feature collection with 15000 features and 1 field
# geometry type: LINESTRING
# dimension: XY
# bbox: xmin: -4.297631 ymin: -4.118291 xmax: 3.782847 ymax: 4.053399
# CRS: NA
# First 10 features:
# id geometry
# 1 1 LINESTRING (0.2780517 0.243...
# 2 2 LINESTRING (0.4261505 2.503...
# 3 3 LINESTRING (0.8662821 -0.11...
# 4 4 LINESTRING (-0.5335952 -0.1...
# 5 5 LINESTRING (1.154309 -1.352...
# 6 6 LINESTRING (0.05512324 -0.4...
# 7 7 LINESTRING (1.945868 -0.744...
# 8 8 LINESTRING (0.0427066 -0.08...
# 9 9 LINESTRING (0.06738045 0.41...
# 10 10 LINESTRING (0.4128964 -0.04...