R语言实现巴西地图坐标叠加与无线电覆盖选区判定
R空间匹配与可视化实现方案
依赖包加载
需要用到空间处理包sf、数据处理包dplyr,搭配已使用的geobr、ggplot2、RColorBrewer,先全部加载:
library(geobr) library(ggplot2) library(sf) library(dplyr) library(RColorBrewer)
1. 无线电覆盖范围转空间多边形
df_1中的radio_wave字段是字符串存储的覆盖边界坐标,先解析为sf格式的多边形空间对象,坐标系采用通用WGS84(EPSG:4326),和经纬度坐标匹配:
# 坐标串解析函数:自动补全缺失分隔符,生成闭合多边形 parse_wave_poly <- function(wave_str) { # 补全坐标对之间缺失的逗号 clean_str <- gsub("(-?\\d+\\.?\\d*)\\s+(-?\\d+\\.?\\d*)", "\\1,\\2", wave_str) # 拆分单个坐标值 coord_vals <- as.numeric(trimws(unlist(strsplit(clean_str, ",")))) coord_vals <- coord_vals[!is.na(coord_vals)] # 转为经纬度矩阵(sf要求顺序为经度、纬度) coords <- matrix(coord_vals, ncol = 2, byrow = TRUE) # 闭合多边形 if(!all(coords[1,] == coords[nrow(coords),])) coords <- rbind(coords, coords[1,]) return(st_polygon(list(coords))) } # 转换为sf空间对象 df_1_sf <- df_1 %>% rowwise() %>% mutate(geometry = list(parse_wave_poly(radio_wave))) %>% st_as_sf(crs = 4326)
2. 空间关联合并,生成覆盖标识字段
将df_2的选举选区经纬度转为点空间对象,通过空间包含判断点是否落在无线电覆盖多边形内,生成要求的covered_by_radio_wave字段:
# 选区数据转sf点对象 df_2_sf <- df_2 %>% st_as_sf(coords = c("longitude", "latitude"), crs = 4326, remove = FALSE) # 空间关联匹配 df_merged <- st_join(df_2_sf, df_1_sf, join = st_within) %>% mutate(covered_by_radio_wave = ifelse(!is.na(Radio_id), "Yes", "No")) %>% st_drop_geometry() # 移除空间列,得到普通数据框
若单个选区被多个无线电信号覆盖,结果会生成多行记录,需要单选区单条记录时,追加
distinct(election_section, .keep_all = TRUE)去重即可。
3. 多图层叠加可视化
按从底到顶的顺序依次添加市政区底图、无线电覆盖范围、发射台点位、选区点位即可实现多图层叠加:
# 读取巴西市政区底图 mun <- read_municipality(code_muni="all", year=2010, showProgress = FALSE) ggplot() + # 市政区底图 geom_sf(data=mun, fill = "white", color = "gray80", linewidth = 0.2) + # 半透明无线电覆盖范围 geom_sf(data=df_1_sf, aes(fill = radio_show), alpha = 0.3, color = NA) + # 发射台点位(三角形标记) geom_sf(data=df_1_sf, aes(color = radio_show), size = 2, shape = 17) + # 选举选区位(按选举结果区分形状) geom_sf(data=df_2_sf, aes(shape = result), size = 3, color = "black") + # 图例与配色设置 scale_fill_brewer(palette = "Set1", name = "电台节目类型") + scale_color_brewer(palette = "Set1", name = "电台节目类型") + scale_shape_manual(values = c(16, 4), name = "选举结果") + coord_sf() + theme_minimal() + theme( panel.grid.major = element_blank(), panel.background = element_rect(fill = "aliceblue"), axis.text = element_blank(), axis.title = element_blank() )
结果验证
运行完成后:
df_merged结构和给出的期望结果一致,covered_by_radio_wave字段准确标识选区是否在覆盖范围内- 生成的地图所有空间要素坐标对齐,可直观看到覆盖范围和选区的位置关系
内容的提问来源于stack exchange,提问作者CelloRibeiro
相关产品推荐
相关产品推荐

