library(tidyverse) library(sf)
read_sf("2019行政区划/市.shp") %>% st_transform(4326) %>% dplyr::filter(!is.na(市)) %>% st_make_valid() -> city
st_intersects(st_make_valid(city), st_make_valid(city), sparse = F) -> touchmat touchmat %>% as_tibble() %>% mutate_all(as.numeric) %>% mutate(市代码 = city$市代码) %>% select(市代码, everything()) %>% set_names(c("市代码", city$市代码)) %>% gather(2:372, 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(1) -> pair1
city %>% dplyr::filter(市代码 == pair1$市代码) -> maincity city %>% dplyr::filter(市代码 == pair1$相邻市) -> touchcity
st_intersection(st_cast(maincity$geometry, "MULTILINESTRING"), st_cast(touchcity$geometry, "MULTILINESTRING")) %>% st_collection_extract("LINESTRING") -> commonline
bind_rows(maincity, touchcity) %>% select(-contains("类型")) %>% st_centroid() -> twocity
twocity %>% mutate( 距离相邻市对共同边界的最小距离 = twocity %>% st_distance(commonline) %>% units::set_units("km") ) %>% mutate(距离相邻市对共同边界的最小距离 = as.numeric(距离相邻市对共同边界的最小距离)) -> citycentroid
citycentroid %>% st_drop_geometry() %>% mutate(pair = paste0(市代码[1], "-", 市代码[2]))
ggplot() + geom_sf(data = maincity, aes(fill = 市), alpha = 0.3) + geom_sf(data = touchcity, aes(fill = 市), alpha = 0.5) + geom_sf(data = commonline, color = "#709ae1", size = 2) + geom_sf(data = citycentroid, 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(maincity$市, "与", touchcity$市, "质心与共同边界的最小距离"), subtitle = "数据计算&绘图:微信公众号 RStata", caption = "注:散点大小表示质心距离两个共同市界的最小距离,图中的蓝色粗线表示两个市的共同市界") + scale_x_continuous(limits = c(115, 120)) + theme(legend.position.inside = c(0.9, 0.5), legend.position = "inside")
|
评论