如何有效地从点创建线串?

Posted

技术标签:

【中文标题】如何有效地从点创建线串?【英文标题】:How to efficiently create Linestrings from points? 【发布时间】:2021-04-06 10:42:18 【问题描述】:

我在两个单独的数据框中有 geom POINT。我想要做的是用一条线连接点(稍后在地图上),这就是为什么我想为这些数据帧中的每对点创建 Linestring。我是这样设计的:

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 在这个数据帧上不能正常工作。我需要在每行的 POINT 之间分别创建线串,如屏幕上所示。

【问题讨论】:

看看@SymbolixAU 的另一个答案:***.com/a/51922422/7547327。它看起来与您的问题相似,您可能可以将其与 sfheaders 一起使用以提高速度。 是的,我也看到了。问题是所有这些函数只接受数值,而不接受几何特征。所以我不能将几何点传递给st_linestringsf_linestring,只能传递数值(例如浮点类型的坐标)。或者也许我错了,我只是注意到了。 【参考方案1】:

如果没有示例数据集,就很难完整地回答您的问题。但是,如果您可以将 data.frame 转换为“长”形式,那么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...

【讨论】:

我有两个带有 geom 列 (POINT) 的单独数据集,在 sfheaders 的情况下,我发现我需要加入它们。我是这样做的:df &lt;- cbind(coordsCust,coordsApp ),然后添加 id:df$id &lt;- seq(1:nrow(df)),最后添加:sfheaders::sf_linestring(obj = df, x = "geometry", y = "geometry.1", linestring_id = "id")。不幸的是,我收到了错误:Not compatible with requested type: [type=list; target=double]. 我还在上面的主帖中添加了一些细节。 似乎我无法在几何点之间实现,只能在浮点/数字坐标之间实现

以上是关于如何有效地从点创建线串?的主要内容,如果未能解决你的问题,请参考以下文章

如何有效地从 Firebase 实时数据库中获取 7 天、30 天的摘要?

有效地从 QPaintDevice 到 QQuickItem 中的 QSGTexture

如何在不使用 Set 的情况下有效地从数组中删除重复项

r - 从数据框中同一行中的两个点创建线串

如何有效地从 jupyter 或 colab 中的数据帧复制输出并以漂亮/可读的格式粘贴到 ***

有效 WKT 线串的正则表达式(在 BigQuery 中)?