library(tidyverse) library(sf)
read_sf("2019行政区划/省.shp") %>% st_transform(4326) %>% dplyr::filter(!is.na(省) & 省 != "中朝共有") %>% st_make_valid() -> prov
st_intersects(st_make_valid(prov), st_make_valid(prov), sparse = F) -> touchmat touchmat %>% as_tibble() %>% mutate_all(as.numeric) %>% mutate(省代码 = prov$省代码) %>% select(省代码, everything()) %>% set_names(c("省代码", prov$省代码)) %>% gather(2:ncol(.), key = "key", value = "value") %>% dplyr::filter(省代码 != key & value == 1) -> pairdf
pairdf
pairdf %>% mutate(key = as.numeric(key)) %>% dplyr::filter(省代码 > key) %>% rename(相邻省 = key) %>% select(-value) -> pairdf
pairdf %>% slice(10) -> pair1
prov %>% dplyr::filter(省代码 == pair1$省代码) -> mainprov prov %>% dplyr::filter(省代码 == pair1$相邻省) -> touchprov
st_intersection(st_cast(mainprov$geometry, "MULTILINESTRING"), st_cast(touchprov$geometry, "MULTILINESTRING")) %>% st_collection_extract("LINESTRING") -> commonline
bind_rows(mainprov, touchprov) %>% select(-contains("类型")) %>% st_centroid() -> twoprov
twoprov %>% mutate( 距离相邻省对共同边界的最小距离 = twoprov %>% st_distance(commonline) %>% units::set_units("km") ) %>% mutate(距离相邻省对共同边界的最小距离 = as.numeric(距离相邻省对共同边界的最小距离)) -> provcentroid
provcentroid %>% st_drop_geometry() %>% mutate(pair = paste0(省代码[1], "-", 省代码[2]))
ggplot() + geom_sf(data = mainprov, aes(fill = 省), alpha = 0.3) + geom_sf(data = touchprov, aes(fill = 省), alpha = 0.5) + geom_sf(data = commonline, color = "#709ae1", size = 2) + geom_sf(data = provcentroid, aes(size = 距离相邻省对共同边界的最小距离), color = "gray20", shape = 16) + scale_fill_manual(values = c("#ff847c", "#99b898"), name = "") + scale_size_continuous(range = c(1, 4), name = "距离相邻省对共同边界\n的最小距离(km)") + labs(title = paste0(mainprov$省, "与", touchprov$省, "质心与共同边界的最小距离"), subtitle = "数据计算&绘图:微信公众号 RStata", caption = "注:散点大小表示质心距离两个共同省界的最小距离,图中的蓝色粗线表示两个省的共同省界") + scale_x_continuous(limits = c(110, 123)) + theme(legend.position.inside = c(0.9, 0.5), legend.position = "inside")
|
评论