You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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()

原理说明

  1. 州界直接由县界合并生成,完全继承县界的边界坐标,不存在两个独立数据源的偏差
  2. 只需要对县界数据做一次位置调整,避免重复操作阿拉斯加、夏威夷带来的坐标误差
  3. 绘制时先画细县界,再叠加粗州界,视觉上州界会覆盖县界的州边缘部分,达到预期效果

内容的提问来源于stack exchange,提问作者Melissa Chen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 10:10:01