leaflet包
LeafletR主要是用R语言的语法封装了JS版的Leaflet,可以在R语言的plot窗口,利用html5技术显示各种地图,还可以绘制自己的要素图形。
它有如下功能:
交互地图浏览(缩放、平移)
使用多种底图进行任意组合
加载地图瓦片(WMTS)
点要素定位标记
多边形要素标记
线要素标记
弹出窗口
解析加载GeoJson
从R或者RSutido创建地图窗口
可以把地图嵌入 knitr/R包所生成的Markdown文档中,或者是Shiny制作的APP中。
可以直接获取通过SP包生成就(加载)的空间对象以及包含经纬度的数据框进行展示。
可以设定地图范围以及封装自定义的鼠标事件。
一般来说,它的基本使用步骤如下:
1、加载leaflet包
2、通过leaflet包创建地图控件。
3、通过图层操作的方法(如addTiles、 addMarkers、 addPolygons)来处理图层数据,并且修改地图插件的各种参数,来把图层显示在地图控件上。
4、可以重复第三步,可以增加更多的图层数据。
5、把地图部件显示出来。完成绘图。
下面来看一个例子:
m <- leaflet()
at <- addTiles(m)
addMarkers(at,lng=116.391, lat=39.912, popup="这里是北京")
leaflet()%>%addTiles()%>%addMarkers(lng=116.391, lat=39.912, popup="这里是北京")
官方的文档里面,对于这种需要重复进行容器嵌套的写法,提供了管道操作符“%>%”来实现,它的主要作用就是把前面的语句(变量)传递给下一个语句,并且作为第一个参数使用,上面那三个语句,利用管道操作符来写,如下,输出结果是完全一样的,但是语句变得简单了。
二、地图控件
在leaflet包初始化的时候,一般调用leaflet()这个方法,这个方法就是对地图控件进行初始化,会生成一个地图容器,以后所有的图层操作,都在这个容器内处理。一般来说,这个方法都被作为其他方法的第一个参数来使用。我们可以通过显示参数设定或者通过管道操作符%>%来把这个容器传递给其他的方法。
地图控件的基本方法有下面这三个:
setView() :设定地图的显示级别缩放比例、和地图的中心点。
fitBounds():设定地图的范围,一般是一个矩形,结构是:[lng1, lat1] – [lng2, lat2]。
clearBounds():清除地图的范围设定。
下面来看个例子:
m<- leaflet()
m<- setView(m,lng=116.38,lat=39.9,zoom=9)
addTiles(m)
或者用管道操作符
leaflet()%>%setView(lng=116.38,lat=39.9,zoom=9)%>%addTiles()
初始化改为3级的话,结果如下:
leaflet()%>%setView(lng=116.38,lat=39.9,zoom=3)%>%addTiles()
leaflet包支持各种与空间信息有关的对象,包括使用sp包定义的空间对象,和R语言中带有空间信息的数据框等,如下所示:
与R相关的:
由经纬度信息组成矩阵
带有经纬度字段的数据框。
与sp包相关的:
SpatialPoints[DataFrame]
Line/Lines
SpatialLines[DataFrame]
Polygon/Polygons
SpatialPolygons[DataFrame]
还有就是maps包里面的各种空间图形信息
这些对象都可以直接用于leaflet里面的方法,作为图层添加到地图上。下面我们通过leaflet来绘制一些地图
当然,最简单的,还是绘制点,通过经纬度,把点画上去,我们先生成一批随机点:
df = data.frame(Lat = rnorm(100), Lon = rnorm(100))
然后画上去:
m <-leaflet(df)
addCircles(m)
#写法2:
df %>%leaflet()%>%addCircles()
leaflet包相对其它地图包,有很多优点和缺点,
首先,绘制地图简单快捷,因为都是基于供应商的tiles,一行代码就可以render出基本widget地图。
支持管道传参,一个图层一个图层进行添加,代码结构更加清晰。
其次,有很多tiles供应商可以选择,包括高德、google、Stamen, Esri, OpenWeatherMap,NASA,
等好几十个tiles供应商。当然其中一些需要注册。其中的google可以绕过注册,已经很难得了。
对于在地图上添加markers图标,shapes形状,线条等,异常方便快捷,这在ggplot2中很难做到的。
支持栅格数据,rasters栅格数据是基于像素点的地图。可以看出,leaflet具有很强的包容性。
支持多种投影坐标系,甚至可以自定义坐标系,这在某些特殊场景非常重要。
当然还有更重要的是,其具有一定交互能力,可以缩放拖拽,
简单的图层切换也不需要使用Shiny。使得更容易上手。
其它特点,首先tiles是基于供应商的,必须联网,
其次对颜色支持不一样,只支持HEX颜色空间和colors()中的颜色名称。 当然内置的几个palette函数,非常特别。
1.Widget设置
Widget地图框的设置,就是确定Widget的基本参数,
包括CRS坐标系,widget的中心坐标,zoom level(缩放)的范围, widget边界坐标,data数据等。
1.1
leafletOptions()
leaflet()中有个options参数,用leafletOptions()函数来指定,可以控制widget缩放范围。
语法:
1leafletOptions(minZoom = NULL, maxZoom = NULL, crs = leafletCRS(),
2 worldCopyJump = NULL, preferCanvas = NULL, …)
关键参数:
minZoom,表示最低缩小倍数,作用于所有地图层。
maxZoom,表示最高放大倍数,作用于所有地图层。
crs, 表示指定坐标系统,
preferCanvas, 表示是否将leaflet.js路径呈现在地图上。
1library(leaflet)
2
3leaflet(options= leafletOptions(minZoom=0, maxZoom =18))
1.2
中心、缩放、边界
关键函数:
setView() ,设定地图的view(包括center位置和zoom level)
flyTo() ,切换到一个指定的location或zoom-level,使用光滑的pan-zoom
fitBounds() ,设定地图矩形区域边界。view将限制在[lng1, lat1] - [lng2, lat2]
flyToBounds() ,切换到一个指定的地图矩形区域边界,使用光滑的pan/zoom
setMaxBounds() ,限定地图矩形区域最大边界
clearBounds() ,清除地图矩形区域边界, 然后view将只会受地图层的经度和纬度数据限制。
语法:
setView(map, lng, lat, zoom, options = list())
flyTo(map, lng, lat, zoom, options = list())
fitBounds(map, lng1, lat1, lng2, lat2, options = list())
flyToBounds(map, lng1, lat1, lng2, lat2, options = list())
setMaxBounds(map, lng1, lat1, lng2, lat2)
ClearBounds (map)
参数解释:
map,表示leaflet()创建的map widget
lng, 表示map center的经度,东经为正
lat, 表示map center的纬度,北纬为正
zoom, 表示zoom level
options, 列表传参,传递zoom或pan参数。
lngl, latl, lng2, lat2, 表示widget边界的坐标。
1library(leaflet)
2
3# 设定中心坐标和zoom level
4m <- leaflet() %>% addTiles() %>% setView(-71.0382679,42.3489054, zoom =18)56
# 显示第一个view
7m %>% fitBounds(-72,40,-70,43)
# 设定view边界89# 显示第二个view
10m %>% clearBounds() # 清除边界限制, leaflet()默认为世界地图
Data数据
这里的Data不仅仅是画地图上行政区域的数据,而且包括要在地图上呈现的数据。
大多数图层添加函数都有data参数,通常使用%>%管道符逐渐传递data参数。
leaflet()通常支持下列几种形式的数据。
矩阵数据(由经度和纬度构成)。
数据框(由经度和纬度构成)。
从sp包传递的数据,包括:
SpatialPoints(数据框类型)
Line()/Lines()
SpatialLines()(数据框类型)
Polygon()/Polygons()
SpatialPolygons()(数据框类型)
从maps包传递的数据,主要是map()函数传递的数据框。
对于经度和纬度组成矩阵或数据框类型数据,在调动data添加图层时,会根据变量名进行猜测匹配:
若变量名称为lat,或latitude等,则猜测为纬度,猜测时,不区分大小写。
若变量名称为lng, long或 longitude等,则猜测为经度,猜测时,不区分大小写。
也可以手动指定经度和纬度变量,使用~语法。
在参数传递过程中,默认后面的data参数覆盖前面data参数。
1.3.1 data中经纬度的指定/猜测/覆盖
1library(leaflet)23# 自动猜测匹配
4set.seed(123)5df <- data.frame(Lat = 1:10, Long = rnorm(10))6leaflet(df)%>%addCircles()78# 手动指定经度和纬度变量,结果一样 leaflet(df) %>% addCircles(lng = ~Long,
9# lat = ~Lat)
1011# 在add_xxx()函数中重新指定参数进行覆盖,结果一样 leaflet() %>%
12# addCircles(data = df) leaflet() %>% addCircles(data = df, lat = ~Lat, lng
13# = ~Long)
1.3.2 sp对象的data
1library(leaflet)
2library(sp)
3library(RColorBrewer)
4
5Sr1 <- Polygon(cbind(c(2,4,4,1,2), c(2,3,5,4,2)))
#4对非重复点坐标,首尾相连
6Sr2 <- Polygon(cbind(c(5,4,2,5), c(2,3,2,2)))
#3对非重复点坐标,画三角形
7Sr3 <- Polygon(cbind(c(4,4,5,10,4), c(5,3,2,5,5)))
#4对非重复点坐标,画四边形
8Sr4 <- Polygon(cbind(c(5,6,6,5,5), c(4,4,3,3,4)), hole = TRUE) # hole = TRUE,表示中空
9
10
11Srs1 <- Polygons(list(Sr1),"s1") #'s1'指定ID参数,多个多边形才有ID参数,Polygon()没有ID参数
12Srs2 <- Polygons(list(Sr2),"s2")
13Srs3 <- Polygons(list(Sr4, Sr3),"s3/4") # 合并Sr3和Sr4多边形
14
15# 列表传参,传递多个多边形参数
16SpP <- SpatialPolygons(list(Srs1, Srs2, Srs3),1:3)
17
18leaflet(height ="300px") %>% addPolygons(data = SpP, fillColor = brewer.pal(3,19name ="Set1"))
1.3.3 从maps包中获取data
1library(leaflet)
2library(maps)
3library(RColorBrewer)
4
5mapStates <- map("state", fill = TRUE, plot = FALSE)
6leaflet(data= mapStates) %>% addTiles() %>% addPolygons(fillColor = brewer.pal(10,7 name="Paired"), stroke = FALSE)
1.3.4 其它参数
其它绘图参数支持R自带的数据类型,如:向量,颜色向量,数据框,同样支持用~指定。
1library(leaflet)
2
3# 随便编一个数据
4m <- leaflet() %>% addTiles()
5df <- data.frame(lat = rnorm(100), lng = rnorm(100),size= runif(100,5,20),
6color= sample(colors(),100))
7
8m <- leaflet(df) %>% addTiles()
9#circle图标的半径不随zoom变化:
10m %>% addCircleMarkers(radius = ~size,color= ~color, fill = FALSE)
11#circle图标的半径不随zoom变化:
12m %>% addCircleMarkers(radius = runif(100,4,10),color= c("red"))
2.Basemaps底图
leaflet支持Tilemap类型的底图,
leaflet支持多种免费第三方providers的tiles, 包括Stamen, Esri, OpenWeatherMap等,
用names(providers)可以查看所有的providers。
2.1
默认Tiles(OpenStreetMap)
使用addTiles()函数添加tiles并使用默认参数,默认即是OpenStreetMap,即街区Tiles。
1library(leaflet)
2
3m <- leaflet()%>%setView(lng = -71.0589, lat = 42.3601, zoom = 12)4m%>%addTiles()# 显示街区图
第三方 Tiles
调用addProviderTiles()函数,在参数providers$后面加tiles供应商的名字就行了。 需要注意:部分第三方tiles需要注册。
通过options参数调用providerTileOptions()函数可以规避部分tiles的注册。
如果有定制的tiles模板的URL链接,可以在addTiles()函数中调用。
1library(leaflet)
2
3m <- leaflet()%>%setView(lng = -71.0589, lat = 42.3601, zoom = 12)
4
5# 使用Stamen.Toner 的 tiles
6m%>%addProviderTiles(providers$Stamen.Toner)
巧妙的数据转换
通过调用函数addWMSTiles()可以添加WMS(Web Map Service)的tiles。
Web地图服务(WMS)是一种标准协议,描述如何通过Internet提供任何地理配准的地图图像,
这通常由使用来自地理信息系统数据库的数据的地图服务器生成。
协议标准由Open Geospatial Consortium(OGC)开发,
并于1999年首次发布.WMS提供了一种使用HTTP接口请求地理注册地图图像的简单方法。
WMS供应商(https://en.wikipedia.org/wiki/Web_Map_Service)
1library(leaflet)
2
3leaflet() %>% addTiles() %>% setView(-93.65,42.0285, zoom =4) %>% # 叠加一个WMS的tiles图层4addWMSTiles("http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi", layers ="nexrad-n0r-900913",
5 options = WMSTileOptions(format ="image/png", transparent = TRUE), attribution ="Weather data <U+00A9> 2012 IEM Nexrad")
Tiles图层叠加
多个Tiles图层也可以叠加, 但是这种情况通常仅用于表层tiles是半透明的情况下,
或在options参数中手动指定不透明度opacity。
opacity从0(完全透明)到1(完全不透明)。
1library(leaflet)
2
3m <- leaflet() %>% setView(lng = -71.0589, lat =42.3601, zoom =12)
4
5m %>% addProviderTiles(providers$MtbMap) %>% # 底层tiles
6 addProviderTiles(providers$Stamen.TonerLines, # 叠加一层tiles,显示公路和街道
7 options = providerTileOptions(opacity =0.35)) %>% # opacity设定非透明度
8 addProviderTiles(providers$Stamen.TonerLabels) # 叠加tiles,显示公路名,街道名,机场图标。
链接:https://blog.csdn.net/R3eE9y2OeFcU40/article/details/88324895