कैसे प्रभावी रूप से अंक से Linestrings बनाने के लिए?

Dec 30 2020

मेरे पास दो अलग-अलग डेटा फ़्रेमों में जियोम पॉइंट्स हैं। मैं जो करना चाहता हूं, वह बिंदुओं को एक लाइन (बाद में मानचित्र पर) के साथ जोड़ना है, इसलिए मैं उन डेटा फ़्रेमों से प्रत्येक जोड़ी बिंदुओं के लिए लिनस्ट्रिंग बनाना चाहता हूं। मैंने इसे इस तरह बनाया है:

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

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

और लिनेस्ट्रिंग:

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

यह कोड काम करता है, मैं प्रत्येक जोड़ी बिंदुओं के लिए पंक्ति द्वारा पंक्ति बना सकता हूं: पंक्ति द्वारा पंक्ति:

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)

मुद्दा यह है कि 30 000 पंक्तियों के लिए यह समाधान वास्तव में धीमी गति से काम करता है - लगभग 21 सेकंड। क्या बिंदुओं से लिनस्ट्रेस बनाने का कोई अन्य तरीका है? कुछ है जो बहुत तेजी से काम करता है? मैंने वेब पर कुछ समाधान खोजे लेकिन व्यर्थ। मैंने sf को मैट्रिक्स में परिवर्तित करने और उपयोग करने के बारे में कुछ पढ़ा है, pmapलेकिन इसे लागू करने का कोई विचार नहीं है।

अद्यतन: अगर मैं sfheaders :: sf_linestring फ़ंक्शन का उपयोग करना चाहता हूं, तो मुझे दोनों डेटासेट से ज्यामिति में शामिल होने की आवश्यकता है। मैं इसे इस तरह से करता हूं:

df <- cbind(coordsCust,coordsApp)

और अंतिम डेटा फ़्रेम (मैंने इसका सबसे महत्वपूर्ण हिस्सा दिखाया) नीचे दिखाया गया है:

दुर्भाग्य से sf_linestring इस डेटाफ़्रेम पर ठीक से काम नहीं करता है। मुझे स्क्रीन पर दिखाए गए अनुसार प्रत्येक पंक्ति के लिए POINTs के बीच लाइनस्ट्रिंग बनाने की आवश्यकता है।

जवाब

2 SymbolixAU Dec 30 2020 at 04:49

बिना किसी अतिशेष डेटा सेट के आपके प्रश्न का पूर्ण उत्तर देना कठिन है। लेकिन अगर आप अपने डेटा.फ्रेम को 'लंबे' रूप में प्राप्त कर सकते हैं, तो sfheadersयह एक पल में कर सकते हैं

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