Bagaimana cara membuat Linestrings dari titik secara efisien?

Dec 30 2020

Saya memiliki POINT geom dalam dua bingkai data terpisah. Yang ingin saya lakukan adalah menghubungkan titik dengan garis (nanti di peta) jadi itulah mengapa saya ingin membuat Linestring untuk setiap pasangan titik dari bingkai data tersebut. Saya membuatnya seperti ini:

coordsCust <- table %>%
  st_as_sf(coords = c("lonCust","latCust"), crs = 4326)

coordsApp <- table %>%
  st_as_sf(coords = c("lonApp","latApp"), crs = 4326) %>%
  st_geometry()

dan Linestring:

lines <- st_sfc(mapply(function(a,b){
  st_cast(st_union(a,b),"LINESTRING")}, 
  coordsCust$geometry, coordsApp$geometry, SIMPLIFY=FALSE))

Kode ini berfungsi, saya dapat membuat Linestrings untuk setiap pasangan poin, baris demi baris:

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)

Masalahnya adalah bahwa untuk 30.000 baris, solusi ini bekerja sangat lambat - sekitar 21 detik. Apakah ada cara lain untuk membuat pegas dari titik? Sesuatu yang bekerja lebih cepat? Saya mencari beberapa solusi di web tetapi sia-sia. Saya telah membaca sesuatu tentang mengubah sf ke matriks dan menggunakan pmaptetapi tidak tahu bagaimana menerapkannya di sini.

UPDATE: jika saya ingin menggunakan sfheaders :: sf_linestring function, saya perlu menggabungkan geometri dari kedua dataset. Saya melakukannya seperti ini:

df <- cbind(coordsCust,coordsApp)

dan bingkai data terakhir (saya tunjukkan bagian terpentingnya) ditunjukkan di bawah ini:

Sayangnya sf_linestring tidak bekerja dengan baik pada dataframe ini. Saya perlu membuat garis batas antara TITIK untuk setiap baris secara terpisah seperti yang ditunjukkan di layar.

Jawaban

2 SymbolixAU Dec 30 2020 at 04:49

Tanpa kumpulan data contoh, sulit untuk menjawab pertanyaan Anda secara lengkap. Tetapi jika Anda bisa mendapatkan data.frame Anda menjadi bentuk 'panjang', maka Anda sfheadersdapat melakukannya dalam sekejap

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...