R_leaflet包_最易上手地图教程(一)(下)

欢迎关注天善智能,我们是专注于商业智能BI,人工智能AI,大数据分析与挖掘领域的垂直社区,学习,问答、求职一站式搞定!
对商业智能BI、大数据分析挖掘、机器学习,python,R等数据领域感兴趣的同学加微信:tstoutiao,邀请你进入数据爱好者交流群,数据爱好者们都在这儿。
作者:李誉辉
四川大学在读研究生
简
介
最近一直在寻找方便上手的地图包,实验了google地图包,百度地图包,发现还是有很多限制。
百度地图包搭配的REmap总是崩溃,
google地图包ggmap现在需要国际信用卡注册,总之,都不甚满意。
虽然ggplot2地图功能非常丰富,但是还是不够简单快捷。
尤其是当我们仅仅需要绘制一些简单的地图时。
经过圈子大佬的推荐,开始尝试leaflet包,确实给我很多惊喜。
leaflet包相对其它地图包,有很多优点和缺点,
首先,绘制地图简单快捷,因为都是基于供应商的tiles,一行代码就可以render出基本widget地图。
支持管道传参,一个图层一个图层进行添加,代码结构更加清晰。
其次,有很多tiles供应商可以选择,包括高德、google、Stamen, Esri, OpenWeatherMap,NASA,
等好几十个tiles供应商。当然其中一些需要注册。其中的google可以绕过注册,已经很难得了。
对于在地图上添加markers图标,shapes形状,线条等,异常方便快捷,这在ggplot2中很难做到的。
支持栅格数据,rasters栅格数据是基于像素点的地图。可以看出,leaflet具有很强的包容性。
支持多种投影坐标系,甚至可以自定义坐标系,这在某些特殊场景非常重要。
当然还有更重要的是,其具有一定交互能力,可以缩放拖拽,
简单的图层切换也不需要使用Shiny。使得更容易上手。
其它特点,首先tiles是基于供应商的,必须联网,
其次对颜色支持不一样,只支持HEX颜色空间和colors()中的颜色名称。 当然内置的几个palette函数,非常特别。
总之,笔者认为leaflet包与ggplot2包的互补性非常好,刚好弥补了ggplot2中画地图的不足。
对于大量数据需要呈现在地图上的场景,还是`ggplot2, leaflet中插入其它plots不便也没有必要。
下面是笔者总结的中文教程,使得新人能更快上手。
说明:以下图片皆为截图,限于技术问题,不能完全展现它的交互式功能。
5.形状与线条
在leaflet中,添加形状和线条非常容易。
多边形和折线
线条和多边形数据源可以从以下途径获取:
SpatialPolygons(), SpatialPolygonsDataFrame(),
Polygons()和Polygon()对象(来自sp包)
SpatialLines(), SpatialLinesDataFrame(), Lines(), 和Line()对象(来自sp包)
MULTIPOLYGON(), POLYGON(), MULTILINESTRING()和LINESTRING()对象(来自sp包)
map()对象(来自maps包)。
使用map(fill = TRUE)得到多边形数据,使用map(fill = FALSE)得到折线段数据
2列的矩阵,第1列为经度,第2列为纬度。多边形之间用(NA, NA)行分开。
但是对于多边形内部存在空洞,这种方法失效,须使用SpatialPolygons()。
5.1
circles形状
使用addCircles()添加circle形状。
绘制circle形状时,仅仅需要圆心坐标和半径。使用radius参数指定半径。
1library(leaflet)
2
3cities <- read.csv(textConnection(“
4City,Lat,Long,Pop
5Boston,42.3601,-71.0589,645966
6Hartford,41.7627,-72.6743,125017
7New York City,40.7127,-74.0059,8406000
8Philadelphia,39.9500,-75.1667,1553000
9Pittsburgh,40.4397,-79.9764,305841
10Providence,41.8236,-71.4222,177994
11″))
12
13leaflet(cities) %>% addTiles() %>% addCircles(lng = ~Long, lat = ~Lat, weight = 1,
14 radius = ~sqrt(Pop) * 30, popup = ~City, fillColor = “magenta”, fillOpacity = 0.2)

5.2
Rectangles矩形
一个矩形仅仅需要2组经纬度数据(对应矩形2个对角点),
分别为lng1, lng2, lat1, lat2共4个数字向量
矩形坐标数据不能像其它多边形一样从sp,maps包或2列矩阵,或2列数据框中得到。
因为其它多边形数据都是1组点的坐标数据(分组连线成多边形),而矩形数据是2组点的坐标数据。
使用addRectangles()函数添加矩形图层。
1library(leaflet)
2
3leaflet() %>% addTiles() %>% addRectangles(lng1 = -118.456554, lat1 = 34.078039,
4 lng2 = -118.436383, lat2 = 34.062717, fillColor = “transparent” # fillColor = ‘transparent’与fillColor = NULL结果不一样
5)

5.3
addPolygons()
语法:
1addPolygons(map, lng = NULL, lat = NULL, layerId = NULL,
2 group = NULL, stroke = TRUE, color = “#03F”, weight = 5,
3 opacity = 0.5, fill = TRUE, fillColor = color, fillOpacity = 0.2,
4 dashArray = NULL, smoothFactor = 1, noClip = FALSE, popup = NULL,
5 popupOptions = NULL, label = NULL, labelOptions = NULL,
6 options = pathOptions(), highlightOptions = NULL,
7 data = getMapData(map))
参数解释:
stroke, 表示是否显示多边形的路径阴影。
color, 表示指定stroke的颜色。
weight, 表示指定stroke像素宽度。
smoothFactor, 表示指定多边形的polyLines(边线)简化因子。越大,则边缘约平滑。
opacity, 表示指定stroke透明度,opacity从0(完全透明)到1(完全不透明)
fillOpacity, 表示指定多边形fill透明度,opacity从0(完全透明)到1(完全不透明)
fillColor, 表示指定多边形fill填充颜色,
highlightOptions, 表示高亮鼠标所在区域的多边形。
指定高亮参数用highlightOptions()函数。
5.3.1 highlightOptions()高亮多边形
高亮多边形,就是改变鼠标所在区域多边形的颜色和透明度等参数。
语法:
1highlightOptions(stroke = NULL, color = NULL, weight = NULL,
2 opacity = NULL, fill = NULL, fillColor = NULL,
3 fillOpacity = NULL, dashArray = NULL, bringToFront = NULL,
4 sendToBack = NULL)
参数解释:
dashArray, 表示指定多边形stroke的线型,与Popup中用法一致。
bringToFront, 表示当鼠标悬浮在所在多边形区域时,
是否将该shape置于表层。这对于高亮shape是必须的。
sendToBack, 表示当鼠标移走时,是否将高亮shape置于底层。
下图为美国人口数据图,数据来源(https://www.census.gov/geo/maps-data/data/cbf/cbf_state.html)需要科学上网。
1library(leaflet)
2
3path <- “E:/R_input_output/data_input/cb_2013_us_state_20m/cb_2013_us_state_20m.shp”
4states <- rgdal::readOGR(path,layer = “cb_2013_us_state_20m”,
5 GDAL1_integer64_policy = TRUE)# 读取数据
6
7neStates <- subset(states, states$STUSPS %in% c(
8 “CT”,”ME”,”MA”,”NH”,”RI”,”VT”,”NY”,”NJ”,”PA”
9))
10
11leaflet(neStates) %>%
12 addPolygons(color = “cyan”, weight = 1, smoothFactor = 0.5,
13 opacity = 1.0, fillOpacity = 0.5,
14 fillColor = ~colorQuantile(“YlOrRd”, ALAND)(ALAND),
15 highlightOptions = highlightOptions(color = “white”, weight = 2, # 高亮形状区域,置于表层。
16 bringToFront = TRUE))
1## OGR data source with driver: ESRI Shapefile
2## Source: “E:R_input_outputdata_inputcb_2013_us_state_20mcb_2013_us_state_20m.shp”, layer: “cb_2013_us_state_20m”
3## with 52 features
4## It has 9 fields
5## Integer64 fields read as doubles: ALAND AWATER

5.3.2 简化polygons/polylines
对于形状复杂的地图多边形和折线,直接使用leaflet绘图容易出现一些问题,
并且运算量大, 因为数据点太多了。
很多时候,对数据进行简化是必要的,
简化后的图形与没有简化的在普通分辨率下根本分辨不出来差别。
使用rmapshaper::ms_simplify()简化很方便,
其基于拓扑学原理进行简化,数据存储量小,形状失真小。
albersusa包安装方式:devtools::install_github(“hrbrmstr/albersusa”)
1library(albersusa)
2
3fullsize <- usa_sf() # albersusa包自带数据
4object.size(fullsize) # object.size属于utils包,R自带
5
6simplified <- rmapshaper::ms_simplify(fullsize)
7object.size(simplified) # 可以看出,这种简化方式存储量只有原来1/8
1## 933016 bytes
2## 123920 bytes
6.GeoJSON与TopoJSON数据
对于GeoJSON和TopoJSON类型数据,有2种处理方式:
要么读取为sp对象;要么使用addGeoJSON()和addTopoJSON()函数。
6.1
直接读取GeoJSON/TopoJSON
GeoJSON格式与TopoJSON格式是不一样的。
**GeoJSON格式文件后缀是”.geojson“。
TopoJSONg格式文件后缀是”.json“**。
地图数据集都可以在线转换,推荐使用GiS Map Converter
支持多种格式免费转换,邮箱注册非常方便。
也可以使用MyGeodata Converter(https://mygeodata.cloud/converter/)
使用addGeoJSON()或addTopoJSON()函数可以直接读取JSON文件,
但是很多参数不能修改,还是转换成sp对象最好。
6.1.1 addGeoJSON()
下面用到的地图数据来自于中国省级地图下载(https://pan.baidu.com/share/init?surl=f5344XfW7X1wqXuTsNONSw)0,密码:vhk6
直接给geojson参数指定文件路径。
注意:使用本地JSON文件或leafletCN绘图,在markdown中码代码,不能直接knitr到html.
Script中码代码可以输出为本地html文件。但是只能在一个html中输出一张图。
所以笔者接下来的图形均使用截图。
1library(leaflet)
2
3filepath <- “E:/R_input_output/data_input/China.geojson”
4
5leaflet() %>%
6 setView(lng = 106.33, lat = 29.35, zoom = 3.5) %>% # 以重庆城区经纬度为中心
7 addTiles() %>%
8 addGeoJSON(geojson = filepath,
9 weight = 1, color = “magenta”, fill = FALSE) # 修改color失败

6.1.2 addTopoJSON()
直接给topojson参数指定文件路径。
1library(leaflet)
2
3filepath <- “E:/R_input_output/data_input/JSON/TopoJson/China.json”
4
5leaflet() %>%
6 setView(lng = 106.33, lat = 29.35, zoom = 3.5) %>% # 以重庆城区经纬度为中心
7 addTiles() %>%
8 addTopoJSON(topojson = filepath, weight = 1,
9 color = “magenta”, fill = FALSE) # 修改color失败

6.2
sp对象
使用geojsonio或rgdal包,读取GeoJSON/TopoJSON对象为sp对象。
然后就能使用sp对象作图。
此方法设置或修改地图区域的特征属性方面更加方便,如colors, labels等。
对于GeoJSON文件,可以用记事本打开看一下数据结构,然后再读取。
也可以用JSON在线解析器(http://geojson.io/#map=2/20.0/0.0)查看,更加方便。
读取GeoJSON还是TopoJson格式,函数的使用方法是一样的。
1library(leaflet)
2library(rgdal)
3
4filepath <- “E:/R_input_output/data_input/JSON/TopoJson/China.json”
5# filepath <- “E:/R_input_output/data_input/JSON/GeoJSON/China.geojson” # 结果一样
6China_map <- readOGR(filepath, stringsAsFactors = FALSE)
7# China_map <- geojsonio::geojson_read(filepath,what = “sp”) # 结果一样
8
9Encoding(China_map@data$name) <- “UTF-8” # 纠正中文字符乱码
10leaflet(China_map) %>%
11 setView(lng = 106.33, lat = 29.35, zoom = 3.5) %>% # 以重庆城区经纬度为中心
12 addPolygons(stroke = TRUE, color = “magenta”, smoothFactor = 0.3,
13 fillOpacity = 0.5,fillColor = “lime”) %>%
14 addMarkers(lng = 114.3,lat = 30.6 ) # 增加一个图标

(图片太大,没截全)
6.3
修改style(样式)
对于GeoJSON/TopoJSO格式数据中的特征属性来说,
有2种方法进行修改(目前仅仅修改paths和shapes, 不支持markers):
其一是在addGeoJSON()和addTopoJSON()函数中设置参数。
另一种方法是对JSON对象(字符串),重新编码styling信息,
通过直接在JSON数据的top level的JSON 对象下面直接插入1个style对象。
下一个代码块是关于设置全局styles和在JSON数据中插入style对象的例子。
在R中不推荐使用这种方法设置styles, 通常还是首先将数据转换成sp对象,再进行绘图更加方便。
但是,如果你掌控了GeoJSON/TopoJSON数据的生成过程,直接插入style对象是可取的。
1library(leaflet)
2library(jsonlite)
3
4filepath <- “E:/R_input_output/data_input/JSON/TopoJson/China.json”
5# filepath <- “E:/R_input_output/data_input/JSON/GeoJSON/China.geojson” # 结果一样
6
7# 首先解析JSON格式为stringified格式,再转化为多级列表
8China_map_list <- readLines(filepath, warn = FALSE) %>%
9 paste(collapse = “”) %>%
10 fromJSON(simplifyVector = FALSE) # 将JSON格式转化为多级列表
11
12# 插入style对象,增加子列表
13China_map_list$style <- list(
14 weight = 1,
15 stroke = “TRUE”,
16 color = “magenta”,
17 fillColor = “lime”,
18 opacity = 0.5,
19 fillOpacity = 0.8
20)
21
22
23# 使用修改了style的JSON数据绘图
24leaflet() %>% setView(lng = 106.33, lat = 29.35, zoom = 3.5) %>% # 以重庆城区经纬度为中心
25 addTopoJSON(China_map_list) %>%
26 # addGeoJSON(China_map_list) %>% # 若读取China.geojson文件,
27 addMarkers(lng = 114.3,lat = 30.6 ) # 增加一个图标

(图片太大,没截全)

往期精彩:
不用代码,从搜索数据中解读星巴克“猫爪杯”如何挠你的心
是否,是否,总是富肥穷瘦?(文末上周投票公布)
R语言自然语言处理:词性标注与命名实体识别
R语言中文社区2018年终文章整理(作者篇)
R语言中文社区2018年终文章整理(类型篇)

转载自:https://blog.csdn.net/R3eE9y2OeFcU40/article/details/88324901