如何在sf中合并相邻多边形并提取独立几何区域?
问题:sf中提取MultiPolygon内的独立连通区域
尝试用sf合并相邻多边形组时,得到了包含非相邻区域的大型MultiPolygon。运行plot(Matsuyama.sf)能看到一个连续大区域和若干岛屿,但无法单独提取这些几何图形。可以将其拆分为数百个Polygon,但尝试的代码又会把它们重新合并为一个,请问问题出在哪?
原始代码:
library(sf) library(tidyverse) Matsuyama.sf <- st_read("https://geoshape.ex.nii.ac.jp/city/geojson/20210101/38/38201A1968.geojson") Matsuyama.sf <- st_transform(Matsuyama.sf, crs=4326) plot(Matsuyama.sf) st_area(Matsuyama.sf)
尝试的拆分与合并代码:
split.sf <- st_cast(Matsuyama.sf, "POLYGON") clumps_1.sf <- st_join(split.sf, split.sf, join = st_intersects) clumps_2sf <- Matsuyama.sf %>% mutate(INTERSECT = st_intersects(.))
解决方案
你之前的方法没有正确识别连通组件(即相互相邻/连通的多边形组),导致合并时又把所有Polygon揉到一起。正确的做法是先给每个Polygon标记所属的连通组,再按组聚合:
- 拆分MultiPolygon为单个Polygon,并添加唯一ID
split.sf <- Matsuyama.sf %>% st_cast("POLYGON") %>% mutate(poly_id = row_number()) # 给每个多边形加唯一标识
- 识别连通组件(用
st_cluster_intersects直接分组)
# 获取每个多边形所属的连通组ID split.sf <- split.sf %>% mutate(cluster_id = as.integer(st_cluster_intersects(.)))
- 按连通组聚合,得到独立的区域(每个区域对应一个MultiPolygon或Polygon)
# 按cluster_id分组合并 clustered_regions <- split.sf %>% group_by(cluster_id) %>% summarize(geometry = st_union(geometry)) %>% ungroup() %>% st_sf() # 确保是sf对象 # 查看结果,每个行对应一个独立区域(主岛或小岛) plot(clustered_regions)
问题原因
st_join(split.sf, split.sf, join = st_intersects)会给每个多边形匹配所有相交的多边形,但未对连通组做标记,后续无法针对性合并;st_intersects(Matsuyama.sf)是对整个MultiPolygon的判断,只会返回自身相交(因为MultiPolygon包含所有区域),无法拆分内部的独立组件。
内容的提问来源于stack exchange,提问作者Mark R
相关产品推荐
相关产品推荐

