我有多边形,我想计算它们之间的重叠百分比。这个想法是,当一个多边形与另一个多边形相交时,可以根据一个多边形或另一个多边形的透视图计算百分比(即最大值)。因此,我想制作一个脚本,生成多边形之间的百分比覆盖率,获取一个多边形和另一个多边形的重叠百分比,并将所有结果放入数据框中。
这是我目前拥有的代码:
set.seed(131)
library(sf)
library(mapview)
m = rbind(c(0,0), c(1,0), c(1,1), c(0,1), c(0,0))
p = st_polygon(list(m))
n = 5
l = vector("list", n)
for (i in 1:n)
l[[i]] = p + 2 * runif(2)
s = st_sfc(l)
s.f = st_sf(s)
s.f$id = c(1,1,2,2,3)
s.f.2 = s.f %>% group_by(id) %>% summarise(geometry = sf::st_union(s)) # %>% summarise(area = st_area(s))
s.f.2$area = st_area(s.f.2)
i = s.f.2 %>%
st_intersection(.) %>%
mutate(intersect_area = st_area(.)) #%>%
st_intersection(s.f.2) %>%
mutate(intersect_area = st_area(.),
# id.int = sapply(i$origins, function(x) paste0(as.character(hr.pol$id)[x], collapse = ", ")),
id1 = sapply(i$origins, function(x) paste0(as.character(s.f.2$id)[x][1])),
id2 = sapply(i$origins, function(x) paste0(as.character(s.f.2$id)[x][2])),
area.id1 = sapply(i$origins, function(x) s.f.2$area[x][1]),
area.id2 = sapply(i$origins, function(x) s.f.2$area[x][2]),
perc1 = as.vector(intersect_area/area.id1),
perc2 = as.vector(intersect_area/area.id2)) %>% # create new column with shape area
filter(n.overlaps ==2) %>%
dplyr::select(id, intersect_area, id1, id2,
# id.int,
perc1,perc2) %>% # only select columns needed to merge
st_drop_geometry() %>% # drop geometry as we don't need it
select(-id) %>%
pivot_longer(#names_prefix = "id",
names_to = "perc",
cols = starts_with("perc"))
这段代码给出了多边形之间重叠的百分比(我只为 2 个重叠做,但如果这可以推广到多个重叠,那就太好了!)
mapview(s.f.2,zcol = "id")
最后,我正在寻找的是这样的:
id `1` `2` `3`
1 100 31.6 0
2 27.0 100 0
3 0 0 100
所以多边形“1”覆盖了多边形“2”面积的 31.6%,多边形“2”覆盖了多边形“1”面积的 27.0%。
我目前拥有的是(但速度很慢):
data.sp = s.f.2 %>%
st_as_sf(.) %>%
mutate(area.m = st_area(geometry),
area.ha = units::set_units(area.m, ha)) %>%
select(-c(area,area.m))
id.sort = sort(unique(data.sp$id)) # used to reorder columns based on ID
df.fill =data.frame(id1 = NULL, id2=NULL, area =NULL, over1 = NULL, over2 = NULL)
for (k in 1:length(id.sort)) {
for (op in 1:length(id.sort)) {
int.out = st_intersection(data.sp[data.sp$id==id.sort[k],],
data.sp[data.sp$id==id.sort[op],])
# int.out
if(nrow(int.out) != 0) {
area.tmp = st_area(int.out)#/10000
over1 = area.tmp/int.out$area.ha
over2 = area.tmp/int.out$area.ha.1
} else {area.tmp = 0;over1=0;over2=0}
df.fill.tmp = data.frame(id1 = id.sort[k], id2=id.sort[op],
area = area.tmp,
over1 = over1*100,
over2 = over2*100)
df.fill = rbind(df.fill,df.fill.tmp)
}
}
df.fill$over1 = as.numeric(df.fill$over1)
df.fill$over2 = as.numeric(df.fill$over2)
df.fill %>%
select(-c(area, over2)) %>%
pivot_wider(names_from = id2,values_from = over1,
values_fill = 0)