有没有一种方法可以在R中合并连续的多线字符串sf对象?

6
我希望有人能帮助我。假设我有七条线段,前四条线段是连续的,而后三条线段也是连续的。没有属性可以用来将它们分组。是否有一种方法可以将前四条线段合并为一个特征,同时将最后三条线段合并为一个特征?
提前感谢您的帮助,并注意安全!
library(sf)

s1 <- st_multilinestring(list(rbind(c(0,3), c(0,4))))
s2 <- st_multilinestring(list(rbind(c(0,4), c(1,5))))
s3 <- st_multilinestring(list(rbind(c(1,5), c(2,5))))
s4 <- st_multilinestring(list(rbind(c(2,5), c(2.5,5))))
s5 <- st_multilinestring(list(rbind(c(2.7,5), c(4,5))))
s6 <- st_multilinestring(list(rbind(c(4,5), c(4.5,4))))
s7 <- st_multilinestring(list(rbind(c(4.5,4), c(5,4))))

sf_ml <- st_sf(section = 1 ,geometry=st_sfc(list(s1,s2,s3,s4,s5,s6,s7)))
plot(sf_ml)

绘图结果

我希望得到类似下面这样的结果:

Simple feature collection with 2 features and 1 field
geometry type:  MULTILINESTRING
dimension:      XY
bbox:           xmin: 0 ymin: 3 xmax: 5 ymax: 5
CRS:            NA
# A tibble: 2 × 2
  section                                           geometry
*   <dbl>                                  <MULTILINESTRING>
1       1 ((0 3, 0 4), (0 4, 1 5), (1 5, 2 5), (2 5, 2.5 5))
2       1         ((2.7 5, 4 5), (4 5, 4.5 4), (4.5 4, 5 4))
1个回答

8

我认为您可以采用以下方法。思路是使用“几何二元谓词”来计算连接和连续线的分组,提取它们的ID,并在按ID分组后合并这些线条。 首先,加载包:

library(sf)
#> Linking to GEOS 3.9.0, GDAL 3.2.1, PROJ 7.2.1
library(igraph)
#> 
#> Attaching package: 'igraph'
#> The following objects are masked from 'package:stats':
#> 
#>     decompose, spectrum
#> The following object is masked from 'package:base':
#> 
#>     union
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:igraph':
#> 
#>     as_data_frame, groups, union
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union

创建数据

s1 <- st_multilinestring(list(rbind(c(0,3), c(0,4))))
s2 <- st_multilinestring(list(rbind(c(0,4), c(1,5))))
s3 <- st_multilinestring(list(rbind(c(1,5), c(2,5))))
s4 <- st_multilinestring(list(rbind(c(2,5), c(2.5,5))))
s5 <- st_multilinestring(list(rbind(c(2.7,5), c(4,5))))
s6 <- st_multilinestring(list(rbind(c(4,5), c(4.5,4))))
s7 <- st_multilinestring(list(rbind(c(4.5,4), c(5,4))))
sf_ml <- st_sf(section = 1 ,geometry=st_sfc(list(s1,s2,s3,s4,s5,s6,s7)))

运行st_touches来查找共享边界点的那些线条的ID。

(my_idx_touches <- st_touches(sf_ml))
#> Sparse geometry binary predicate list of length 7, where the predicate
#> was `touches'
#>  1: 2
#>  2: 1, 3
#>  3: 2, 4
#>  4: 3
#>  5: 6
#>  6: 5, 7
#>  7: 6

我们可以看到第一个和第二个几何图形共享一个边界点,以此类推。然后,我们将这个对象转换为图形对象。

(my_igraph <- graph_from_adj_list(my_idx_touches))
#> IGRAPH fb199d0 D--- 7 10 -- 
#> + edges from fb199d0:
#>  [1] 1->2 2->1 2->3 3->2 3->4 4->3 5->6 6->5 6->7 7->6

我们可以看到,第一个多线段与第二个多线段相连,以此类推。最后,我们可以通过函数components()的输出返回的名为membership的对象来提取连接线的组。

(my_components <- components(my_igraph)$membership)
#> [1] 1 1 1 1 2 2 2

前四个几何形状属于一组,另外三个几何形状属于另一组。最后,我们可以使用summarise()函数将同一组中的线合并起来。
sf_ml2 <- sf_ml %>% 
  group_by(section = as.character({{my_components}})) %>% 
  summarise()

检查打印

sf_ml2
#> Simple feature collection with 2 features and 1 field
#> Geometry type: MULTILINESTRING
#> Dimension:     XY
#> Bounding box:  xmin: 0 ymin: 3 xmax: 5 ymax: 5
#> CRS:           NA
#> # A tibble: 2 x 2
#>   section                                           geometry
#>   <chr>                                    <MULTILINESTRING>
#> 1 1       ((0 3, 0 4), (0 4, 1 5), (1 5, 2 5), (2 5, 2.5 5))
#> 2 2               ((2.7 5, 4 5), (4 5, 4.5 4), (4.5 4, 5 4))

以及一个图表

plot(sf_ml2, lwd = 2)

这段内容是使用 reprex工具 (v2.0.1) 在2021年09月14日创建的。


同一个问题(或者说类似问题)和同一个答案:https://gis.stackexchange.com/questions/310462/cluster-geometries-that-touch-each-other - agila
非常感谢!我真的很感激。顺便问一下,如果我使用st_intersects而不是st_touches,有什么区别吗?再次感谢,注意安全! - dslr
st_intersects 返回 true,如果两个几何体共享任何部分空间,而 st_touches 返回 true,如果两个几何体共享边界点 --> st_touchesst_intersects 更严格。 - agila
我问的原因是因为当我使用相同的代码处理连续重叠的多边形时,它不起作用。但是当我使用st_intersects时,它可以正常工作。无论如何,再次感谢你的帮助。 - dslr
st_touches 对于重叠的多边形“无效”(除非它们之间唯一重叠的区域在它们的边界并集中)。请查看 https://postgis.net/docs/ST_Touches.html 和 https://postgis.net/docs/ST_Intersects.html 获取更多示例。 - agila
我明白了。再次感谢! - dslr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接