Leaflet 与高德继续碰撞火花!

简介: 我们对 leaflet 包做了一期简单的入门教程:空间地理数据可视化之 leaflet 包及其拓展。之后,又将高德和该包相结合,介绍了前期需要准备的工作,见:Leaflet 与高德合并会擦出怎么样的火花?。这一期就到了绘制地图环节,下面将分享三类数据的绘制教程。

前言


我们对 leaflet 包做了一期简单的入门教程:空间地理数据可视化之 leaflet 包及其拓展。之后,又将高德和该包相结合,介绍了前期需要准备的工作,见:Leaflet 与高德合并会擦出怎么样的火花?。这一期就到了绘制地图环节,下面将分享三类数据的绘制教程。


本文框架


这篇推文讲的是第三节内容


3. 绘制地图


3.1 散点地图绘制

  1. 将高德地图替换 leaflet 自带的底图

由于 leaflet 自带的底图不是很合规,所以我们使用高德地图进行替换。

library(leaflet)
geo_map <- leaflet(width = '100%') %>% 
  addTiles(
    urlTemplate = 'http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
    layerId = tileOptions(minZoom = 3, maxZoom = 17),
    attribution = NULL
  )
  1. 在地图上增加标记

使用addMarkers()geo_map上增加散点图。

geo_map %>% 
  addMarkers(
    data = datafile,  ## 存放有坐标的文件
    lat = ~lat,       ## 变量纬度(latitude)所在列
    lng = ~lng,       ## 变量经度(longitude)所在列
    label = ~address  ## 变量标签所在列(这里设置了详细的地址作为标签)
    )

  1. 批量下载 api 地址

高德地图地理编码的 api 每天可以查询 30 万次,所以可以将上述查询过程写成一个 function 来进行批量查询。代码如下,代码中的注释已做详细解释。

## 加载packages
library(dplyr)
library(tidyr)
library(leaflet)
## 设置文件
datafile <- data.frame(
  id = 1:9,
  address = c(
    "北京市东城区天安门广场人民英雄纪念碑",
    "上海市浦东新区东方明珠广播电视塔",
    "台湾省台北市南京东路台北体育馆",
    "海南省海口市海口站(出站口)",
    "香港特别行政区湾仔区岛湾仔博览道1号会议展览中心香港回归祖国纪念碑",
    "澳门特别行政区花王堂区澳门博物馆大炮台(北入口)",
    "西藏拉萨市城关区布达拉宫广场西藏和平解放纪念碑",
    "新疆克拉玛依市平南八路克拉玛依北站",
    "黑龙江省哈尔滨市道里区斯大林街20号哈尔滨市人民防洪胜利纪念塔"
  )
)
## 自定义function
gaodemap <- function(x){
  address <- stringr::str_replace_all(datafile$address[x], "[^[:alnum:]]", "") ## 去除特殊字符,部分特殊字符会导致查询失败,所以在最开始直接去除
  url <- paste0(
    'https://restapi.amap.com/v3/geocode/geo?',
    '&key=', key, ## key
    '&address=', address, ## 详细地址
    '&output=', 'JSON'
  )
  temp_geo <- fromJSON(paste(readLines(url,warn = F, encoding = 'UTF-8'), collapse = ""))
  status <- temp_geo$status ## 判断查询是否成功
  if (status == 1 & length(temp_geo$geocodes) != 0){ ## 有时候成功了但是没有收到数据,所以用了一个“且”进行判定
    temp <- paste(datafile$address[x], temp_geo$geocodes$location, sep = ",")
  } else {
    temp <- paste(datafile$address[x], 'NULL,NULL', sep = ",")
  }
  return(temp)
}
## 地理编码
df <- data.frame(
  geo = sapply(datafile$id, gaodemap, simplify = T)
) %>% 
  separate(col = geo, into = c('address', 'lng', 'lat'), sep = ',') ## 分割function的结果
df$lng <- as.numeric(df$lng)
df$lat <- as.numeric(df$lat)
df
##                                                             address       lng
## 1                              北京市东城区天安门广场人民英雄纪念碑 116.39768
## 2                                  上海市浦东新区东方明珠广播电视塔 121.50003
## 3                                    台湾省台北市南京东路台北体育馆 121.54067
## 4                                        海南省海口市海口站(出站口) 110.16203
## 5 香港特别行政区湾仔区岛湾仔博览道1号会议展览中心香港回归祖国纪念碑 114.17738
## 6                    澳门特别行政区花王堂区澳门博物馆大炮台(北入口) 113.54620
## 7                    西藏拉萨市城关区布达拉宫广场西藏和平解放纪念碑  91.11885
## 8                                新疆克拉玛依市平南八路克拉玛依北站  85.08215
## 9      黑龙江省哈尔滨市道里区斯大林街20号哈尔滨市人民防洪胜利纪念塔 126.61724
##        lat
## 1 39.90462
## 2 31.23925
## 3 25.05213
## 4 20.02724
## 5 22.28094
## 6 22.19486
## 7 29.65127
## 8 45.56794
## 9 45.78065
  1. 绘图

这里我们将上面获得的df数据进行绘制,可以得到以下图形

geo_map <- leaflet(width = '100%') %>% 
  addTiles(
    urlTemplate = 'http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
    layerId = tileOptions(minZoom = 3, maxZoom = 17),
    attribution = NULL
  )
geo_map %>% 
  addMarkers(
    data = df,
    lat = ~lat, 
    lng = ~lng, 
    label = ~address
    )

补充:如果数据量较大,可以考虑使用 parallel 和 foreach 等来实现并行访问和解析 api,因为 R 语言默认是单核运行的,所以会出现**“一核有难,多核围观”**的情形,使用并行运算可以使电脑发挥出多核的优势,提升数据处理速度。

您可能会发现高德限制每秒 api 访问量是 200 次,多核并行会超限,就我的经验而言每次访问和解析大概需要 0.1 秒,16 线程并行查询 api,一秒钟也就160次,更何况还存在网络波动,所以基本上不用担心超限问题。


3.2 路径地图绘制

  1. 按照画线图的经验,平面直角坐标系中的一条线的位置由两个点决定,而两个点位置由它们分别的坐标 (X, Y)  决定,同理路径地图上的线由起点和终点决定,起点和终点由它们对应的经纬度决定,这样子我们就可以知道绘制路径地图的数据至少需要 4 个值,分别表示起点的经纬度和终点的经纬度。
  2. 知道了绘图需要的基本数据,后面的就简单了,只要分别查询两个点的经纬度把他们合并到一个表就好了,这里就不赘述了。有数据的朋友也可以直接把数据整理下就行,下面的例子使用上面绘制散点地图的数据。
  3. 先把数据整理下,假如说希望画从北京到另外 8 个点的直线,我只要在上表中新增一个点作为线段起点就好
df_line <- df %>%  
  mutate(              
    lat_start = lat[1], ## 新增起点纬度
    lng_start = lng[1]  ## 新增起点经度
  )
df_line
##                                                             address       lng
## 1                       北京市东城区天安门广场人民英雄纪念碑 116.39768
## 2                                  上海市浦东新区东方明珠广播电视塔 121.50003
## 3                                    台湾省台北市南京东路台北体育馆 121.54067
## 4                                        海南省海口市海口站(出站口) 110.16203
## 5 香港特别行政区湾仔区岛湾仔博览道1号会议展览中心香港回归祖国纪念碑 114.17738
## 6                    澳门特别行政区花王堂区澳门博物馆大炮台(北入口) 113.54620
## 7                    西藏拉萨市城关区布达拉宫广场西藏和平解放纪念碑  91.11885
## 8                                新疆克拉玛依市平南八路克拉玛依北站  85.08215
## 9      黑龙江省哈尔滨市道里区斯大林街20号哈尔滨市人民防洪胜利纪念塔 126.61724
##        lat lat_start lng_start
## 1 39.90462  39.90462  116.3977
## 2 31.23925  39.90462  116.3977
## 3 25.05213  39.90462  116.3977
## 4 20.02724  39.90462  116.3977
## 5 22.28094  39.90462  116.3977
## 6 22.19486  39.90462  116.3977
## 7 29.65127  39.90462  116.3977
## 8 45.56794  39.90462  116.3977
## 9 45.78065  39.90462  116.3977
  1. 分组合并下数据
df_line <- data.frame(
  group = rownames(df_line),
  lat = c(df_line$lat, df_line$lat_start),
  lng = c(df_line$lng, df_line$lng_start)
) %>% 
  group_by(group) %>% 
  arrange(.by_group = TRUE)
df_line
## # A tibble: 18 x 3
## # Groups:   group [9]
##    group   lat   lng
##    <chr> <dbl> <dbl>
##  1 1      39.9 116. 
##  2 1      39.9 116. 
##  3 2      31.2 122. 
##  4 2      39.9 116. 
##  5 3      25.1 122. 
##  6 3      39.9 116. 
##  7 4      20.0 110. 
##  8 4      39.9 116. 
##  9 5      22.3 114. 
## 10 5      39.9 116. 
## 11 6      22.2 114. 
## 12 6      39.9 116. 
## 13 7      29.7  91.1
## 14 7      39.9 116. 
## 15 8      45.6  85.1
## 16 8      39.9 116. 
## 17 9      45.8 127. 
## 18 9      39.9 116.
  1. 绘图
geo_map <- leaflet(width = '100%') %>% 
  addTiles(
    urlTemplate = 'http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
    layerId = tileOptions(minZoom = 3, maxZoom = 17),
    attribution = NULL
  )
geo_map %>% 
  addPolylines(
    data = df_line,  ## 存放有坐标文件 
    lng = ~lng,  ## 变量经度(longitude)所在列
    lat = ~lat,  ## 变量纬度(latitude)所在列
    group = ~group,  ## 线条分组
    weight = 1,  ## 线条粗细
    color = "red" ##线条颜色
  )

image.gifimage.gif


3.3 导航路径图

这个是看高德地图的时候无意中发现的,高德还提供 api 来查询导航路径,详细可见:官方说明文档[1]

  1. 通过地理编码获得起点和终点的经纬度,方法同上不再赘述了。
address1 <- '福建省厦门市厦门高崎国际机场' ## 起点详细地址
address2 <- '福建省厦门市厦门大学思明校区' ## 终点详细地址
url1 <- paste0(  ## 查询起点的url
  "https://restapi.amap.com/v3/geocode/geo?address=", address1,
  "&output=JSON&key=", key
) 
url2 <- paste0(  ## 查询终点的url
  "https://restapi.amap.com/v3/geocode/geo?address=", address2,
  "&output=JSON&key=", key
)
address1 <- fromJSON(paste(readLines(url1,warn = F, encoding = 'UTF-8'), collapse = "")) ## 起点坐标
address2 <- fromJSON(paste(readLines(url2,warn = F, encoding = 'UTF-8'), collapse = "")) ## 终点坐标
print(address1$geocodes) 
##                formatted_address country province citycode   city district
## 1 福建省厦门市湖里区高崎国际机场    中国   福建省     0592 厦门市   湖里区
##   township neighborhood.name neighborhood.type building.name building.type
## 1     NULL              NULL              NULL          NULL          NULL
##   adcode street number             location  level
## 1 350206   NULL   NULL 118.137053,24.539473 兴趣点
print(address2$geocodes)
##                    formatted_address country province citycode   city district
## 1 福建省厦门市思明区厦门大学思明校区    中国   福建省     0592 厦门市   思明区
##   township neighborhood.name neighborhood.type building.name building.type
## 1     NULL              NULL              NULL          NULL          NULL
##   adcode street number             location  level
## 1 350203   NULL   NULL 118.093470,24.437154 兴趣点
  1. 按照说明文档要求,生成url。
url <- paste0(
  "https://restapi.amap.com/v5/direction/bicycling?", 
  ## 使用骑行路线的api,如果是步行或者驾车,需要按照说明文档修改即可
  "&output=", "JSON",
  "&key=", key,
  '&origin=', address1$geocodes$location, ## 设置起点经纬度
  '&destination=', address2$geocodes$location,  ## 设置终点经纬度
  '&show_fields=', 'polyline' ## 设置显示坐标点
)
## 查询api
address <- fromJSON(paste(readLines(url,warn = F, encoding = 'UTF-8'), collapse = ""))
  1. 导航路径的经纬度信息分成不同段的储存在“route-paths-steps-polyline”中。
head(address$route$paths$steps[[1]]$polyline)
## [1] "118.13766;....
  1. 整理数据
## 经纬度分割开
datafile <- lapply(1:length(address[["route"]][["paths"]][["steps"]][[1]][["polyline"]]), function(x){
    df <- strsplit(address[["route"]][["paths"]][["steps"]][[1]][["polyline"]][[x]], ";")
    return(df)
})
## 转化成表格
df <- data.frame(
  id = matrix(unlist(datafile))
) %>% 
  separate(id, c('lng', 'lat'), ",") %>% 
  mutate_if(is.character, as.numeric)
  1. 绘制地图
leaflet(df, width = '100%') %>% 
  addTiles(
    urlTemplate = 'http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
    layerId = tileOptions(minZoom = 3, maxZoom = 17),
    attribution = NULL
  ) %>% 
  addPolylines(  ## 绘制路线
    lat = ~lat, 
    lng = ~lng
    ) %>% 
  addMarkers(  ## 绘制起点所在点
    lat = ~lat[1], 
    lng = ~lng[1], 
    label = paste0('起点:', address1$geocodes$formatted_address)
    )%>% 
  addMarkers( ## 绘制终点所在点
    lat = ~lat[nrow(df)], 
    lng = ~lng[nrow(df)], 
    label = paste0('终点:', address2$geocodes$formatted_address)
    )

目录
相关文章
|
5月前
|
数据可视化 大数据 定位技术
地图开发汇总
地图开发汇总
38 0
|
6月前
|
前端开发 JavaScript 搜索推荐
UniApp TabBar的巅峰之作:个性化导航的魅力
UniApp TabBar的巅峰之作:个性化导航的魅力
277 0
|
vr&ar 开发工具
一起来云赏月把!three.js实现vr赏月!
一起来云赏月把!three.js实现vr赏月!
180 0
一起来云赏月把!three.js实现vr赏月!
|
存储 安全 定位技术
高德地图开发汇总
高德地图主要分为地图开发、导航开发、定位开发、室内地图、室内定位。总结一下在项目中用到的地图开发。 Demo地址 DEMO比较简单,集成了3d地图和搜索sdk,可以根据自己的需求添加功能。
1482 0
|
开发框架 数据可视化 算法
惊艳!人人都能玩转酷炫的数据可视化,高德LOCA 2.0全新升级,轻松实现海量数据渲染
“一图胜千言”,大数据时代来临,数据与人们生活密切相关。复杂难懂且体量庞大的数据给人的感觉总是冷冰冰的,让人难以获取到重点信息,也找不出规律和特征,数据价值发挥不出来。空间数据可视化就是为了解决这些问题,用通俗易懂的图形符号还原数据,表达多纬度数据信息,让你的数据“活”起来!
621 0
惊艳!人人都能玩转酷炫的数据可视化,高德LOCA 2.0全新升级,轻松实现海量数据渲染
|
机器学习/深度学习 人工智能 编解码
|
设计模式 缓存 移动开发
高德智慧景区随身听播放器框架设计与实现
我们开发选型并没有采用传统的TTS技术(由文本内容生成机器语音),而是采用了更加通用音频格式(比如mp3),作为讲解的音频输入源,方便讲解者进行二次创作。本文将简单回顾高德智慧景区随身听播放器的框架设计与实现。
高德智慧景区随身听播放器框架设计与实现
|
机器学习/深度学习 传感器 算法
阿里巴巴高德地图首席科学家任小枫QA答疑汇总丨视觉+地图技术有哪些新玩法?
上周,阿里巴巴高德地图首席科学家任小枫在#大咖学长云对话#的在线直播活动上就计算机视觉相关技术发展以及在地图出行领域的应用与大家做技术交流,直播间互动火爆,尤其在QA环节,学弟学妹们纷纷就感兴趣的视觉应用、AR导航、定位技术、5G、职业发展等话题提问,任小枫做了精彩回答。
阿里巴巴高德地图首席科学家任小枫QA答疑汇总丨视觉+地图技术有哪些新玩法?
|
机器学习/深度学习 自然语言处理 算法
免费下载 | 全景揭秘阿里文娱智能算法
文娱大脑究竟能有多“智能”?答案是全生命周期的人工智能技术!从内容智能到增长营销,全景揭秘阿里文娱智能算法,就在这一本!
11735 0
免费下载 | 全景揭秘阿里文娱智能算法