【问题标题】:Create Multilines from Points, grouped by ID with sf package从点创建多线,使用 sf 包按 ID 分组
【发布时间】:2018-06-25 22:04:15
【问题描述】:

我有一个点集合,有一个 LINEID 和一个 ID_SEQ。 LINEID 确定唯一的 Line-IDS,而 ID_SEQ 确定 Line-ID 中点的顺序。

我想将点转换为线,按 ID_SEQ 排序并按 LINEID 分组

使用sp 包,我能够达到预期的效果,但我想使用sf 包来做到这一点。我在这里错过了什么?

这里有一些虚拟数据,用sp-functions 说明了想要的结果,两次尝试用sf 做同样的事情,但是图表显示了不同的结果。

library(sp)
library(sf)

sfpoints <- {
structure(list(LINEID = c(4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 
4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 10L, 10L, 
10L), ID_SEQ = c(10L, 11L, 12L, 13L, 16L, 30L, 31L, 32L, 33L, 
34L, 35L, 36L, 37L, 38L, 39L, 40L, 41L, 42L, 43L, 44L, 45L, 46L, 
1L, 2L, 3L), geometry = structure(list(structure(c(15.423568, 
47.06248), class = c("XY", "POINT", "sfg")), structure(c(15.423644, 
47.062523), class = c("XY", "POINT", "sfg")), structure(c(15.423691, 
47.062553), class = c("XY", "POINT", "sfg")), structure(c(15.423712, 
47.06257), class = c("XY", "POINT", "sfg")), structure(c(15.423716, 
47.062576), class = c("XY", "POINT", "sfg")), structure(c(15.423712, 
47.062588), class = c("XY", "POINT", "sfg")), structure(c(15.423731, 
47.062595), class = c("XY", "POINT", "sfg")), structure(c(15.423779, 
47.062626), class = c("XY", "POINT", "sfg")), structure(c(15.423835, 
47.062664), class = c("XY", "POINT", "sfg")), structure(c(15.423879, 
47.062714), class = c("XY", "POINT", "sfg")), structure(c(15.423897, 
47.062767), class = c("XY", "POINT", "sfg")), structure(c(15.423862, 
47.062828), class = c("XY", "POINT", "sfg")), structure(c(15.423783, 
47.062897), class = c("XY", "POINT", "sfg")), structure(c(15.423681, 
47.062973), class = c("XY", "POINT", "sfg")), structure(c(15.423564, 
47.06306), class = c("XY", "POINT", "sfg")), structure(c(15.423437, 
47.063164), class = c("XY", "POINT", "sfg")), structure(c(15.42331, 
47.06327), class = c("XY", "POINT", "sfg")), structure(c(15.423186, 
47.063385), class = c("XY", "POINT", "sfg")), structure(c(15.423062, 
47.063496), class = c("XY", "POINT", "sfg")), structure(c(15.422941, 
47.063602), class = c("XY", "POINT", "sfg")), structure(c(15.422821, 
47.063717), class = c("XY", "POINT", "sfg")), structure(c(15.422699, 
47.063824), class = c("XY", "POINT", "sfg")), structure(c(15.422518, 
47.061687), class = c("XY", "POINT", "sfg")), structure(c(15.422617, 
47.06179), class = c("XY", "POINT", "sfg")), structure(c(15.422717, 
47.061893), class = c("XY", "POINT", "sfg"))), class = c("sfc_POINT", 
"sfc"), precision = 0, bbox = structure(c(15.422518, 47.061687, 
15.423897, 47.063824), .Names = c("xmin", "ymin", "xmax", "ymax"
), class = "bbox"), crs = structure(list(epsg = NA_integer_, 
proj4string = NA_character_), .Names = c("epsg", "proj4string"
), class = "crs"), n_empty = 0L)), .Names = c("LINEID", "ID_SEQ", 
"geometry"), row.names = c(NA, -25L), class = c("sf", "data.frame"
), sf_column = "geometry", agr = structure(c(NA_integer_, NA_integer_
), .Names = c("LINEID", "ID_SEQ"), .Label = c("constant", "aggregate", 
"identity"), class = "factor"))}

par(mfrow=c(1,3))

## SP - way
tstssp <- as(sfpoints, "Spatial")
tstssp <- SpatialLines(lapply(split(tstssp, tstssp$LINEID), function(x) 
  Lines(list(Line(coordinates(x))), x$LINEID[1L])))
plot(tstssp, col=1:2, lwd=3, main="SP-Desired Result")


## SF - way ???
tst <- sfpoints %>% 
  group_by(LINEID) %>% 
  st_coordinates() %>%
  st_linestring()
plot(st_geometry(tst), col=1:2 , main="SF-Wrong Result")

tst <- sfpoints %>% 
  group_by(LINEID) %>%
  summarise() %>%
  st_cast("LINESTRING")
plot(st_geometry(tst), col=1:2, main="SF-Wrong Result")

【问题讨论】:

  • 几天前我遇到了一个非常相似的问题。在sf github 上有一些问题报告:github.com/r-spatial/sf/issues/325github.com/r-spatial/sf/issues/321st_union 似乎没有注意数据框中的顺序,而是根据彼此最近的点进行排序。
  • 在我的情况下,我最终按 ID 拆分数据帧,并使用了 gtfsr 包中的 shapes_df_as_sfg,然后将它们重新绑定在一起并转换为线串。不幸的是,我无法适应你的科幻
  • 感谢您的回复。我已经看到了那些 github 问题,但它们对我的情况没有帮助。我唯一能做的就是更改为 sp 结构,将点拆分为线,然后转换回 sf.. 但我没有看到 st_union 采用最近的下一个点,因为这会在情节 3 中产生正确的结果,所以我仍然想知道它如何将这些点结合在一起,从而输出这种锯齿形结构。
  • 我错误地说它是最近的点,我认为它实际上是通过增加经度值来排序的,这就是你最终得到之字形的方式
  • 这可以解释奇怪的形状。太糟糕了,我不能通过 ID_SEQ 告诉他正确的顺序..

标签: r casting sf


【解决方案1】:

正如 Edzer 在 this issue 中解释的那样,您必须为 summarise 函数提供参数 do_union = FALSE

tst <- sfpoints %>% 
  group_by(LINEID) %>%
  summarise(do_union = FALSE) %>%
  st_cast("LINESTRING")
plot(st_geometry(tst), col=1:2)

【讨论】:

  • 漂亮!!我多次阅读该问题并错过了关键部分do_union = FALSE。非常感谢!!!
猜你喜欢
  • 2019-08-26
  • 1970-01-01
  • 2020-06-21
  • 1970-01-01
  • 2019-11-28
  • 2022-10-25
  • 1970-01-01
  • 2021-09-22
  • 1970-01-01
相关资源
最近更新 更多