如何在R绘制的含县界美国地图中加粗州界并保证对齐?
解决美国州界与县界叠加对齐问题
我想要绘制包含美国全部50个州及对应县的地图,要求加粗州界同时保持县界为细线条。我尝试分别处理县界和州界数据并调整阿拉斯加、夏威夷的位置,但叠加后两者边缘无法精准对齐,尤其是阿拉斯加和夏威夷地区,即使使用了相同的CRS转换参数。
解决方案:从县界数据聚合生成州界
不要单独调用states()获取州界数据,直接从已处理好的县界数据中按州聚合生成州界,这样州界会完全匹配县界的边界,从根源上解决对齐问题。
以下是完整的实现代码:
library(tigris) library(sf) library(dplyr) library(ggplot2) # 1. 处理县界数据(包含阿拉斯加、夏威夷位置调整) map_sf <- tigris::counties(cb = T, class = 'sf') # 移除美国海外领地 map_sf <- map_sf %>% filter(!STATEFP %in% c('60', '66', '69', '72', '78')) # 用于调整位置的投影CRS crs_lambert <- "+proj=laea +lat_0=45 +lon_0=-100 +x_0=0 +y_0=0 +a=6370997 +b=6370997 +units=m +no_defs" map_sf <- map_sf %>% st_transform(crs = crs_lambert) # 调整阿拉斯加位置 alaska <- map_sf %>% filter(STATE_NAME == 'Alaska') alaska_g <- st_geometry(alaska) alaska_centroid <- st_centroid(st_union(alaska_g)) rot <- function(a) matrix(c(cos(a), sin(a), -sin(a), cos(a)), 2, 2) alaska_trans <- (alaska_g - alaska_centroid) * rot(-39 * pi/180) / 2.3 + alaska_centroid + c(1000000, -5000000) alaska <- alaska %>% st_set_geometry(alaska_trans) %>% st_set_crs(crs_lambert) # 调整夏威夷位置 hawaii <- map_sf %>% filter(STATE_NAME == 'Hawaii') hawaii_g <- st_geometry(hawaii) hawaii_centroid <- st_centroid(st_union(hawaii_g)) hawaii_trans <- (hawaii_g - hawaii_centroid) * rot(-35 * pi/180) + hawaii_centroid + c(5200000, -1400000) hawaii <- hawaii %>% st_set_geometry(hawaii_trans) %>% st_set_crs(crs_lambert) # 合并调整后的阿拉斯加、夏威夷到主数据 map_sf <- map_sf %>% filter(!STATE_NAME %in% c('Alaska', 'Hawaii')) %>% rbind(alaska) %>% rbind(hawaii) %>% rename(county = "NAMELSAD", state = "STUSPS") %>% select(county, state, geometry) # 转换为经纬度投影(可选,按需调整) crs_longlat <- "+proj=longlat +lat_0=45 +lon_0=-100 +x_0=0 +y_0=0 +a=6370997 +b=6370997 +units=m +no_defs" map_sf <- map_sf %>% st_transform(crs = crs_longlat) # 2. 从县界数据聚合生成州界 map_states <- map_sf %>% group_by(state) %>% summarise(geometry = st_union(geometry)) %>% ungroup() # 3. 绘制地图:先画县界(细线条),再画州界(加粗) ggplot() + geom_sf(data = map_sf, fill = NA, linewidth = 0.2) + # 细县界 geom_sf(data = map_states, fill = NA, linewidth = 1, color = "black") + # 粗州界 theme_minimal()
原理说明
- 州界直接由县界合并生成,完全继承县界的边界坐标,不存在两个独立数据源的偏差
- 只需要对县界数据做一次位置调整,避免重复操作阿拉斯加、夏威夷带来的坐标误差
- 绘制时先画细县界,再叠加粗州界,视觉上州界会覆盖县界的州边缘部分,达到预期效果
内容的提问来源于stack exchange,提问作者Melissa Chen
相关产品推荐
相关产品推荐

