楚新元 | All in R

Welcome to R Square

用 R 调用高德地图实现网点位置可视化

楚新元 / 2022-04-05


最近要对各网点进行现场检查以及出台总行部室对口帮扶营业网点工作方案,所以有必要对现有网点的情况做一些了解,至少是各个网点的位置得有一个了解吧,这样可以提前将现场检查的路线规划一下,另外有些比较忙人还比较少的部门,可以适当考虑安排个比较近的网点。在好奇心的驱使下,正好这两天有点空闲时间,用代码实现下这个需求,希望将来能用到,也希望对各位看官有所启发。

大体思路是利用官网公布的网点地址信息,调用高德地图API获取各个网点的经纬度,然后根据经纬度信息做一个散点图。当然如果有其他数据也可以放在图上,比如根据网点存款数据在图上增加一个图层做一个柱状图等等。这里先把阶段性的成果放上来:

# 利用爬虫抓取各网点地址信息
branch = XML::readHTMLTable(
  "http://www.hmccb.com/plus/list.php?tid=83",
  header = TRUE, 
  encoding = "UTF-8"
)[[1]]

# 对抓取的信息进行清洗加工
colnames(branch) = branch[1, ]  # 第一行设为字段名
branch = branch[-1, ]  # 去掉第一行

branch$城市 = c(  # 增加城市字段
  rep("哈密市", 20), 
  rep("乌鲁木齐市", 9)
)

branch$名称 = gsub("哈密市商业银行", "", branch$名称)
branch$名称 = gsub("乌鲁木齐市", "", branch$名称)
branch$名称 = gsub("乌鲁木齐", "", branch$名称)

# 编写一个根据位置批量生成经纬度的函数
location = function(city, address) {
  
  # 定义一个高德API Key
  key = Sys.getenv("key")

  # 根据city和address信息生成县区和经纬度
  url = paste0(
    'https://restapi.amap.com/v3/geocode/geo?key=', key, 
    '&city=', city,
    '&address=', address
  ) 
  url |>
    xml2::read_html(encoding = 'utf-8') |>
    rvest::html_text() |>
    jsonlite::fromJSON() |> 
    tidyr::as_tibble() |> 
    tidyr::unnest_wider(geocodes) |> 
    dplyr::select(location) -> df
  return(df[1, 1])
  
}

# 利用函数生成所有网点经纬度信息
library(dplyr)
branch |> 
  rename(
    number = "序号",
    branch = "名称",
    address = "地址",
    telphone = "联系电话",
    city = "城市"
  ) |> 
  arrange(as.numeric(number)) |> 
  mutate(
    jw = purrr::map2(
      city, 
      address, 
      ~ location(.x, .y)
    )
  ) |> 
  tidyr::separate(
    jw, 
    into = c("long", "lat"), 
    sep = ","
  ) -> full_info

# 乌鲁木齐市网点可视化地图
library(ggplot2)
full_info |>   
  filter(city == "乌鲁木齐市") |> 
  ggplot() + 
  geom_point(
    aes(x = long, y = lat),
    size = 6, color = "blue",
    alpha = 0.6
  ) + 
  geom_text(
    aes(x = long, y = lat, label = branch),
    colour = "black", size = 4, vjust = -1
  ) + 
  theme(
    axis.title = element_blank(),
    axis.text = element_blank(),
    axis.ticks = element_blank(),
    # panel.background = element_blank()
  )