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

2019-03-07  本文已影响2人  天善智能

欢迎关注天善智能,我们是专注于商业智能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年终文章整理(类型篇)

上一篇下一篇

猜你喜欢

热点阅读