失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > R_leaflet包_最易上手地图教程(二)

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

时间:2018-12-02 14:53:32

相关推荐

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

作者:李誉辉

四川大学在读研究生

这次,我们接着上一篇讲

7.Colours着色

将变量映射到颜色是地理信息可视化的一个重要组成部分。

为了实现数值映射到颜色色值,leaflet中内置了一些color*开头的函数,

非常方便将数值变量与颜色进行匹配,然后产生一个palette函数。

这些palette函数, 能够根据输入数字向量返回一个ARGB颜色空间的向量。

ARGB颜色空间与HEX颜色空间类似,如“#AARRGGBB”中,前2个十六进制的数代表透明度,

后面三组数字分别代表Red, green, blue。具体见(/p/dedqca/argb-colors-in-android)。

leaflet中有4个palette生成函数。

colorNumeric(),colorBin()colorQuantile(),(均针对连续数字变量)。

colorFactor(),(针对类别型变量)。

使用方法如下:

1library(leaflet)

2

3#调动颜色函数,生成一个palette函数

4pal<-colorNumeric(c("red","green","blue"),1:10)

5#给色板函数传进一个数字向量,返回颜色色值向量。

6pal(c(1,6,9))

1##[1]"#FF0000""#52E74B""#6754D8"

7.1

公共参数

4个颜色函数拥有几个公共参数:palettedomain

palette参数用于指定要与数据匹配的颜色向量,有下面几种指定形式:

RColorBrewer包中palette的名字,eg: “RdYlBu”, “Accent”, “Greens”。

viridis中的palette的名字,如:“viridis”, “magma”, “inferno”, “plasma”。

颜色向量,可以由色条函数生成,也可HEX色值组成的向量。

如:palette(),topo.colors(10)c("#000000", "#0000FF", "#FFFFFF")

其它使用0到1之间的数字生成颜色向量的函数,

如:colorRamp(c("#000000", "#FFFFFF"), interpolate = "spline")

domain参数用于确定输入值的范围。

可以指定domain = NULL,则生成的palette函数没有预设范围,

当调用该palette函数时,会根据传入数据自动确定范围。

但当对不同数据应用同一个palette函数多次,最好具体指定domain参数为非null, 这样数据与颜色才会匹配。

alpha用于指定透明度。

reverse,为逻辑值,用于翻转颜色与输入数字变量的匹配顺序。

7.2

连续数字变量

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'#

6#结果一样

7China_map<-readOGR(filepath,stringsAsFactors=FALSE)

8#China_map<-geojsonio::geojson_read(filepath,what='sp')#结果一样

9Encoding(China_map@data$name)<-"UTF-8"#纠正中文字符乱码

10

11#编造GDP向量

12set.seed(234)

13values_fabricate<-runif(34,0.1,0.9)*2000#全国34个行政区

14China_map$GDP_fabricate<-c(values_fabricate,NA)#经过China_map$name查询最后一个为占位

15

16map_draw<-leaflet(China_map)%>%setView(lng=106.33,lat=29.35,zoom=3.5)#以重庆城区经纬度为中心

1##OGRdatasourcewithdriver:GeoJSON

2##Source:"E:\R_input_output\data_input\JSON\TopoJson\China.json",layer:"中国"

3##with35features

4##Ithas11fields

7.2.1连续型数据,连续型颜色(colorNumeric())

首先,我们尝试将GDP值与RColorBrewer中的“Blues”色条进行匹配。

我们使用colorNumeric()函数创建一个映射函数。

“Blues”色条是仅仅包含9种颜色的离散色板,但是colorNumeric()函数能够插值然后返回连续性色板。

palette参数仅仅是一个颜色向量,只需要注意其中的元素顺序。不一定非要RColorBrewer色板,其它也行,

甚至自定义都行,如:c("white", "navy")c("#FFFFFF", "#000080")

palette长度不等,长度为3也行,这样适合多级渐变,如diverging palette两极渐变。

甚至可以传递一个函数,指定数值在[0, 1]区间外应该返回的颜色。

第2个参数,domain, 用于指定与颜色向量匹配的输入数字。

对于colorNumeric()而言,可以用数字指定范围(最大值/最小值),也可以用数字向量指定。

colorNumeric()函数返回的结果,pal色条函数,

可以接受在range(countries$gdp_md_est)范围内的数字向量,

然后返回ARGB格式的颜色向量。

1library(leaflet)

2library(rgdal)

3

4Npal<-colorNumeric(palette="YlGnBu",domain=China_map$GDP_fabricate)

5

6map_draw%>%addPolygons(stroke=TRUE,smoothFactor=0.3,fillOpacity=0.8,

7color=~Npal(GDP_fabricate))#默认fillColor=color

7.2.2连续型数据,离散型颜色(colorBin(),colorQuantile())

colorBin()相当于对数据切片分箱,将数字性向量数据与固定数量的颜色输出相匹配。

可以通过指定breaks分割点来分箱,也可以指定分箱数来分箱,通过参数bin

注意在按分箱数分箱时,如果pretty = TRUE(默认),

将得到nice round的分割点,但是可能分箱数并不非你指定的。

1library(leaflet)

2

3Bpal<-colorBin(palette="Blues",China_map$GDP_fabricate,6,pretty=FALSE)

4

5map_draw%>%addPolygons(stroke=FALSE,smoothFactor=0.2,fillOpacity=1,

6color=~Bpal(GDP_fabricate))

colorQuantile()同样是对输入数据进行分箱,只是每个子集中的observation数量相等,

默认分成4个箱子,5个breaks。

1library(leaflet)

2

3Qpal<-colorQuantile("Blues",China_map$GDP_fabricate,n=7)

4map_draw%>%addPolygons(stroke=FALSE,smoothFactor=0.2,fillOpacity=1,

5color=~Qpal(GDP_fabricate))

7.3

类别型数据着色

对于类别型数据(categorical data), 使用colorFactor()函数生成色板函数。

如果palette包含的颜色数量与因子水平一致,则为一一对应匹配。

否则,palette中的颜色将会进行插值,然后产生合适数量的颜色。

可以通过给domain参数指定一个因子或字符串向量,或直接用levels参数指定因子水平。

levels参数优先级比domain更高,如同时指定,则会忽略domain参数

1library(leaflet)

2

3#生成一些随机levels

4China_map$category<-as.factor(c(sample.int(5L,34,TRUE),NA))

5

6Fpal<-colorFactor(topo.colors(5),China_map$category)#因为是因子对象,第2个参数与levels参数匹配

7

8leaflet(China_map)%>%

9setView(lng=106.33,lat=29.35,zoom=3.5)%>%#以重庆城区经纬度为中心%>%

10addPolygons(stroke=FALSE,smoothFactor=0.2,fillOpacity=1,

11color=~Fpal(category))

8.Legends图例

Leaflet包中,创建图例也非常方便,

这个小节中,我们将在Colors小节基础上创建图例。

使用addLegend()函数添加图例,最方便的方法是:

colorNumeric()等函数产生的色板函数指定给addLegend()函数中的pal参数, 然后指定values参数,

就会自动计算图例箱体的颜色和刻度标签。

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")#结果一样

8Encoding(China_map@data$name)<-"UTF-8"#纠正中文字符乱码

9

10#编造GDP向量

11set.seed(234)

12values_fabricate<-runif(34,0.1,0.9)*2000#全国34个行政区

13China_map$GDP_fabricate<-c(values_fabricate,NA)#经过China_map$name查询最后一个为占位

14

15map_draw<-leaflet(China_map)%>%

16setView(lng=106.33,lat=29.35,zoom=3.5)#以重庆城区经纬度为中心

17

18Npal<-colorNumeric(palette="YlGnBu",domain=China_map$GDP_fabricate)

19

20map_draw%>%

21addPolygons(stroke=FALSE,smoothFactor=0.2,fillOpacity=1,

22color=~Npal(GDP_fabricate))%>%

23

24addLegend("bottomright",pal=Npal,values=~GDP_fabricate,#生成图例

25title="China.GDP(fabricate)",#图例标题

26labFormat=labelFormat(prefix="¥",suffix="(亿元)"),#标签增加前缀后缀

27opacity=1)

addLegend()函数与palette函数的类型有关,

对不同类型的palette,会生成不同形式的图例。

比较上图中基于colorNumeric()函数生成的图例,

与下图中基于colorQuantile()生成的图例,可以发现:

后者显示大概范围,图例刻度标签也不同。

1library(leaflet)

2

3Qpal<-colorQuantile("RdYlBu",China_map$GDP_fabricate,n=5,reverse=TRUE)#分位数分箱,5等分,reverse=TRUE翻转颜色

4map_draw%>%addPolygons(stroke=FALSE,smoothFactor=0.2,fillOpacity=1,

5color=~Qpal(GDP_fabricate))%>%addLegend(pal=Qpal,values=~GDP_fabricate,

6opacity=1)

addLegend()还有其它几个参数,使得能够以多种方式定制图例,

还有colorslabels参数,具体指定可以定制与大图不一样颜色和标签图例。 还可以定制图例标题和colors的透明度。

使用labFormat = labelFormat()参数,在labelFormat()函数中,可以定制刻度标签显示。

如可以定制刻度标签中内的分隔符,保留小数位数,每个图例的prefix/suffix(前缀或后缀)。

如果你的刻度标签样式超出了labelFormat()函数多能提供的,

还可以使用自定义函数作为labFormat的参数。

具体见?addLegend()

9.Show/Hide 图层

leaflet中有专门的函数来显示或隐藏layers,

用户能够自行设定要显示或隐藏哪些layers.

控制方式有2种:

使用Shiny,在Shiny中使用serve-side代码控制。

笔者对Shiny了解不是很透彻,这里展开了,详细见

(https://rstudio.github.io/leaflet/shiny.html)

add*开头的图层添加函数内,设定group参数。

然后使用addLayersControl()函数增加图层交互框。

9.1

groups分组

group是layers上的一个标签,表示给layers分组。

add*开头的函数中,通过group参数给layers赋予组别属性。格式如下:

1library(leaflet)

2

3leaflet()%>%

4addTiles()%>%

5addMarkers(data=coffee_shops,group="Food&Drink")%>%#指定group参数

6addMarkers(data=restaurants,group="Food&Drink")%>%

7addMarkers(data=restrooms,group="Restrooms")

一个group可以包含多个layers,但每个layer只能最多属于一个group。

Group与Layer IDs特点:

layer IDs 是为了给每一个marker或shape提供单独的识别ID。

通常用字符串向量指定markers或shapes的layersId。其向量长度与markers数量相同。

group仅仅是一个字符串。

不同类型的特征的layer IDs可以相同,如markers与shapes可以是相同的layerIds

因为不同类型的特征其移除函数不同(remove*clear*开头的函数),所有不会相互干扰。

如果给一个circle圆形指定一个layer ID,后续又给一个shape赋予同一个layer ID,

那么前面的circle圆形将自动从地图中移除。

而groups分组是为了使不同的items属于同一个组别。

通常,我们将所有的addMarkers()命令分配到同一个组别。即根据类别进行分组。

后续使用另外的addXXX()也能添加到前面已经存在的group组别中。

9.2

layers交互框

在leaflet中,使用addLayersControl()函数添加layer切换开关。

这样在widget地图中就能用鼠标切换layers。如下图所示,widget上出现了一个按钮框。

一个widge地图中,只能设置一个layerControl交互框,如果存在多个则以最后一个为准。

关键参数:

baseGroups, 可以在baseGroups内几个组别中切换,只能同时查看其中一个组别的图层。 圆形按钮为baseGroups选项。

overlayGroups, 可以选择查看其中显示多个组别的图层或全部隐藏。

勾选按钮为overlayGroups选项。

options, 用addLayerControl()函数指定,可以通过position函数设置交互框的相对位置。

1library(leaflet)

2data(quakes)

3

4outline<-quakes[chull(quakes$long,quakes$lat),]#索引子数据框

5

6map<-leaflet(quakes)%>%#设置basegroup

7addTiles(group="OSM(default)")%>%addProviderTiles(providers$Stamen.Toner,

8group="Toner")%>%addProviderTiles(providers$Stamen.TonerLite,group="TonerLite")%>%

9#设置Overlaygroups

10addCircles(~long,~lat,~10^mag/5,stroke=F,group="Quakes")%>%addPolygons(data=outline,

11lng=~long,lat=~lat,fill=F,weight=2,color="#FFFFCC",group="Outline")%>%

12

13#设置layers切换

14addLayersControl(baseGroups=c("OSM(default)","Toner","TonerLite"),overlayGroups=c("Quakes",

15"Outline"),options=layersControlOptions(collapsed=FALSE))

16

17map

9.3

图标簇分组

如果将markers clusters图标簇分成不同的group组。

当按照marker小节中那样添加markers时,

leaflet就能根据group将markers分成不同的簇了。 这样就能设定不同组别的图标簇显示/隐藏了。

1library(leaflet)

2

3quakes<-quakes%>%

4#mutate列运算,产生新列,新列名为mag.level

5dplyr::mutate(mag.level=cut(mag,c(3,4,5,6),#分箱,breaks为3,4,5,6。

6labels=c('>3&<=4','>4&<=5','>5&<=6')))

7

8quakes.df<-split(quakes,quakes$mag.level)#将quakes根据mag.level分组,变成3个元素的列表

9

10l<-leaflet()%>%addTiles()

11

12names(quakes.df)%>%

13purrr::walk(function(df){#walk迭代,

14l<<-l%>%#深度赋值,l会变成全局变量

15addMarkers(data=quakes.df[[df]],#闭包索引

16lng=~long,lat=~lat,

17label=~as.character(mag),

18popup=~as.character(mag),

19group=df,

20clusterOptions=markerClusterOptions(removeOutsideVisibleBounds=F),

21labelOptions=labelOptions(noHide=F,direction='auto'))

22})

23

24l%>%

25addLayersControl(

26overlayGroups=names(quakes.df),

27options=layersControlOptions(collapsed=FALSE)

28)

walk函数

https://d-rug.github.io/images/1026/1023_DRUG_map_walk.html#41

10.Choropleths(等值线图)

leaflet中画等值线图非常容易,

10.1

数据源

首先需要加载JSON格式的数据,在JS中可以直接加载,

在R中,我们可以使用geojsonio包来加载JSON格式数据,并读取为sp对象。 在sp对象中,我们更加方便操纵地图特征。

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'#

6#结果一样

7China_map<-readOGR(filepath,stringsAsFactors=FALSE)

8#China_map<-geojsonio::geojson_read(filepath,what='sp')#结果一样

9Encoding(China_map@data$name)<-"UTF-8"#纠正中文字符乱码

10

11#编造GDP向量

12set.seed(234)

13values_fabricate<-runif(34,0.1,0.9)*2000#全国34个行政区

14China_map$GDP_fabricate<-c(values_fabricate,NA)#经过China_map$name查询最后一个为占位

15

16map_draw<-leaflet(China_map)%>%setView(lng=106.33,lat=29.35,zoom=3.5)#以重庆城区经纬度为中心

1##OGRdatasourcewithdriver:GeoJSON

2##Source:"E:\R_input_output\data_input\JSON\TopoJson\China.json",layer:"中国"

3##with35features

4##Ithas11fields

10.2

底图着色

1library(leaflet)

2

3#通过手动分箱添加颜色,这样就不是等分

4bins<-c(200,500,800,1200,1500,1800)#分箱的分割点

5Bpal<-colorBin("YlOrRd",domain=China_map$GDP_fabricate,

6bins=bins)#通过分箱生成palette函数

7

8map_draw%>%

9addPolygons(stroke=TRUE,smoothFactor=0.2,

10fillOpacity=0.7,

11fillColor=~Bpal(GDP_fabricate),

12weight=2,

13opacity=1,

14color="lime",

15dashArray="3")%>%

16

17addLegend("bottomright",pal=Bpal,values=~GDP_fabricate,#生成图例

18title="China.GDP(fabricate)",#图例标题

19labFormat=labelFormat(prefix="¥",suffix="(亿元)"),#标签增加前缀后缀

20opacity=1)

10.3

区域高亮

接下来给地图多边形增加交互性,要求当鼠标掠过多边形上时,多边形会高亮。

即在addPolygons()内设置高亮参数highlight

1library(leaflet)

2

3map_draw%>%

4addPolygons(stroke=TRUE,smoothFactor=0.2,

5fillOpacity=0.7,

6fillColor=~Bpal(GDP_fabricate),

7weight=2,

8opacity=1,

9color="lime",

10dashArray="3",

11highlight=highlightOptions(#增加高亮参数

12weight=5,

13color="cyan",

14dashArray="",

15fillOpacity=0.3,

16bringToFront=TRUE)

17)%>%

18

19addLegend("bottomright",pal=Bpal,values=~GDP_fabricate,#生成图例

20title="China.GDP(fabricate)",#图例标题

21labFormat=labelFormat(prefix="¥",suffix="(亿元)"),#标签增加前缀后缀

22opacity=1)

在Leaflet.js中,还可以设置当鼠标点击多边形区域时,放大该区域。

但R中还不行,除非可以在Shiny中设置。

10.4

定制info

接下来,我们将在地图上显示各州的名称和人口密度。

虽然在Shiny中,可以设置当鼠标悬浮在形状区域时,显示info。

然而,这次我们将使用leaflet内置函数中的labels特征来实现。

我们将使用一段HTML语法来产生labels, 然后将其传递给lappy(htmltools::HTML)

这样leaflet就知道将所有labels当作HTML语法来处理,而不是纯文本。

同时,我们也会通过labelOptions参数来设置labels的风格。

1library(leaflet)

2

3#sprintf字符串格式化输出,%s表示将China_map$name当作字符串插入,%g表示小写e记法数字格式化。

4labels<-sprintf(

5"<strong>%s</strong><br/>%gpeople/m<sup>2</sup>",#HTML语法,<br/>表示换行符,

6China_map$name,China_map$GDP_fabricate

7)%>%

8

9lapply(htmltools::HTML)#对向量labels中每个元素进行了HTML处理,全当作HTML处理

10

11map_draw_2<-map_draw%>%

12addPolygons(

13stroke=TRUE,smoothFactor=0.2,

14fillOpacity=0.7,

15fillColor=~Bpal(GDP_fabricate),

16weight=2,

17opacity=1,

18color="lime",

19dashArray="3",

20highlight=highlightOptions(#增加高亮参数

21weight=5,

22color="cyan",

23dashArray="",

24fillOpacity=0.3,

25bringToFront=TRUE),

26label=labels,

27labelOptions=labelOptions(

28style=list("font-weight"="normal",padding="3px8px"),

29textsize="15px",

30direction="auto"))%>%

31

32addLegend("bottomright",pal=Bpal,values=~GDP_fabricate,#生成图例

33title="China.GDP(fabricate)",#图例标题

34labFormat=labelFormat(prefix="¥",suffix="(亿元)"),#标签增加前缀后缀

35opacity=1)

36

37map_draw_2

11.投影坐标系(CRS)

注意,该功能可能不支持部分函数。

addRasterImage()目前仅仅支持EPSG:3857 Web Mercator投影坐标系。

leaflet希望所有的经纬度数据都是基于WGS 84(a.k.a.EPSG:4326)投影坐标系的,

即对这个支持最好。

leaflet中,默认将基于EPSG:3857坐标系投影任何数据。 希望任何的tiles的坐标数据都是基于EPSG:3857坐标系来产生的。

很多时候,用户需要使用不同的投影坐标系来展示数据。

leaflet已经内置了Proj4Leaflet(/kartena/Proj4Leaflet)插件。

这使leaflet在理论上可以访问Proj4js(/)支持的任何CRS

注意,用户使用的任何tiles, 在设计时就必须考虑到与leaflet内CRS的匹配性

11.1

自定义CRS

一旦你决定要自定义一个CRS了,并且有能与之匹配的tiles。

那么你可以使用leafletCRS()来自定义一个CRS。

1library(leaflet)

2

3crs<-leafletCRS(crsClass="L.Proj.CRS",code="ESRI:10",proj4def="+proj=aea+lat_1=29.5+lat_2=45.5+lat_0=37.5+lon_0=-96+x_0=0+y_0=0+datum=WGS84+units=m+no_defs",

4resolutions=1.5^(25:15))#设置分辨率,每个像素点代表多少米,用于缩放

leafletCRS()函数内,有下面几个关键参数:

crsClass参数表示指定要使用的JavaScript构造器,以此来产生leaflet.js CRS对象。

在这里,我们使用L.Proj.CRS,这是Proj4Leaflet带来的class。

只有CRS classes列表中的CRS classes才有效。?leafletCRS查看详情,所有的classes如下:

(L.CRS.EPSG3857, L.CRS.EPSG4326, L.CRS.EPSG3395, L.CRS.Simple, L.Proj.CRS)

code参数表示CRS标识符,通常使用EPSG相关的标识符或相似的标识符。

在大多数情况下,这个参数其实没什么影响,因为其主要在Proj4Leaflet中被使用,在R中很少用。

proj4def参数是一个PROJ.4或WKT类型的字符串,用于定义CRS。

如果你对PROJ.4或WKT了解,那么你可以在epsg.io(https://epsg.io/)或(/)中找到需要的字符串。

通过参数crs = leafletOptions(crs = ...).,

可以将leafletCRS()产生的对象传递给leaflet()函数。

11.2

基于自定义的CRS添加tiles底图

下面的例子显示的是瑞典的哥德堡城市,以EPSG:3006(SWEREF99 TM)坐标系进行投影。

1library(leaflet)

2

3#自定义CRS投影坐标系

4epsg3006<-leafletCRS(crsClass="L.Proj.CRS",code="EPSG:3006",

5proj4def="+proj=utm+zone=33+ellps=GRS80+towgs84=0,0,0,0,0,0,0+units=m+no_defs",

6resolutions=2^(13:-1),#设置分辨率,每个像素点代表多少米,用于缩放,从8192到0.5

7origin=c(0,0)#原点坐标

8)

9

10tile_url<-"/tile/osm-bright-3006/{z}/{x}/{y}.png"

11tile_attrib<-"Mapdata&copy;<ahref='/copyright'>OpenStreetMapcontributors</a>,Imagery&copy;<ahref='http://www.kartena.se/'>Kartena</a>"

12

13#绘widget图

14leaflet(options=leafletOptions(worldCopyJump=F,crs=epsg3006))%>%#指定crs参数

15setView(11.965053,57.70451,13)%>%

16addTiles(urlTemplate=tile_url,#使用URL上的模板

17attribution=tile_attrib,#widget下面的小字,表示tileslayer的属性,为HTML语法

18options=tileOptions(minZoom=0,maxZoom=14,continuousWorld=T))%>%

19addMarkers(11.965053,57.70451)

再次强调,学会使用leafletCRS()函数自定义CRS,

并基于该CRS投影坐标系添加tiles底图,非常重要。

事实上,上图中,来自 服务商的tiles正是基于EPSG:3006产生的。

我们可以通过使用默认的EPSG:3857来绘制一个类似的地图,与上图进行比较。

如果自定义的CRS正常工作,则marker会出现在相同的位置:

1library(leaflet)

2

3leaflet()%>%setView(11.965053,57.70451,16)%>%addTiles()%>%addMarkers(11.965053,

457.70451)

11.3

基于自定义的CRS添加shapes

产生Tiles基于的CRS,必须与leafletCRS()中自定义的CRS相同。

我们经常使用基于WGS 84坐标系的经纬度数据,来添加markers, circles, polygons和lines。

leaflet会自动使用该坐标系来投影上诉特征。

下面的例子是基于EPSG:2163(美国国家地图集等轴投影坐标系)坐标系。

我们使用albersusa包中数据集usa_sf, 事实上并没有使用Albers投影坐标系。

该地图集中,阿拉斯加和夏威夷群岛,被旋转和调整大小过,以使其更靠近美国大陆。

1library(leaflet)

2library(sp)

3library(albersusa)

4

5spdf<-rmapshaper::ms_simplify(usa_sf(),keep=0.1)#简化polygons数据集

6

7pal<-colorNumeric("Blues",domain=spdf$pop_)#产生palette函数

8

9#自定义CRS

10epsg2163<-leafletCRS(

11crsClass="L.Proj.CRS",

12code="EPSG:2163",

13proj4def="+proj=laea+lat_0=45+lon_0=-100+x_0=0+y_0=0+a=6370997+b=6370997+units=m+no_defs",

14resolutions=2^(16:7))#设置分辨率,每个像素代表多少米,用于缩放

15

16#基于CRS坐标系和spdf数据集,绘制地图

17leaflet(spdf,options=leafletOptions(crs=epsg2163))%>%#使用自定义的CRS

18addPolygons(weight=1,color="#444444",opacity=1,#设置边界线线宽,颜色,透明度

19fillColor=~pal(pop_),fillOpacity=0.7,

20smoothFactor=0.5,

21label=~paste(name,pop_),

22labelOptions=labelOptions(direction="auto"))

11.4

极地投影坐标系

有时候也会需要使用极地投影坐标系,

相比其它投影坐标系,可能会遇到更多的问题,甚至与其它Leaflet.js插件不兼容性问题。

可以参考的Bhaskar Karambelkar的案例

(/bhaskarvk/leaflet-polarmaps)

12.附加特征

常用附加特征包括:

leaflet Measure(刻度尺)

Graticule(网格线)

Terminator(白天黑夜指示器)

Minimap(小地图)

12.1

Leaflet Measure 刻度尺

使用addMeasure()可以在地图上添加刻度尺插件。

(/ljagis/leaflet-measure)

刻度尺使用方法:

首先用鼠标点击刻度尺,然后在提示框中点击Create a new measurement就激活刻度尺了。

然后再地图上连续点击2点就能绘制一条线段。

随之提示框中会显示线段的长度Path distance

然后点击Finish measurement按钮,就能将线段保留显示。

连续点击3个及以上的点,且不在一条直线上,则随之显示折线长度,增加显示面积Area

点击Finish measurement按钮就将面积区域保留显示。

1library(leaflet)

2

3m<-leaflet()%>%addTiles()

4

5m%>%

6fitBounds(-73.9,40.75,-73.95,40.8)%>%#fitBounds设定地图矩形区域边界,定到纽约中央公园

7addMeasure()#添加刻度尺插件,默认位置在widget右上角

addMeasure()函数内有很多可选参数用来设置插件的外观和behavior。详情见?addMeasure

关键参数:

position,表示指定刻度尺按钮相对位置。

primaryLengthUnit, 表示指定测量长度时显示的主要长度单位,

主要长度后面的括号内为可选参数,表示次要长度单位secondaryLengthUnit

primaryAreaUnit, 表示指定测量面积时显示的主要长度单位,

同样括号内为次要面积单位secondaryAreaUnit

activeColor,表示指定激活刻度尺时,在地图上点击点,连线时,点和线及面的颜色。

用HEX色值表示。

completedColor, 表示点击Finish measurement后,点和线及面的颜色。同样为HEX色值。

1library(leaflet)

2

3m%>%

4fitBounds(13.76134,52.675499,13.0884,52.33812)%>%#设定边界到德国柏林

5addMeasure(

6position="bottomleft",#设定刻度尺相对位置为左下角

7primaryLengthUnit="meters",#设定测量长度时显示的主要长度单位

8primaryAreaUnit="sqmeters",#设定测量面积时显示的主要面积单位

9activeColor="#00ffff",#=cyan,激活刻度尺时,点线面的颜色。

10completedColor="#ff00ff")#=magenta,表示Finish测量后,点线面的颜色。

12.2

Graticule网格线

使用addGraticule()函数可以给地图添加一个grid网格(通过Leaflet.Graticule插件)。

关键参数:

interval, 表示指定网格线之间间距。

style, 表示网格线的样式,列表传参

可以设定网格线线型dashArray,线宽weight,颜色color,透明度Opacity等。

layerIdgroup,结合group参数和addLayersControl()函数可以添加开关。

1library(leaflet)

2

3m<-leaflet()%>%addTiles()%>%setView(0,0,2)

4m%>%addGraticule()

1library(leaflet)

2#添加2种网格线,间距不一样,线宽不一样,颜色也不一样

3m%>%addGraticule(interval=30,

4style=list(color="#00ffff",weight=4))%>%#="cyan"

5addGraticule(interval=70,style=list(color="#ff00ff",weight=2))#="magenta"

group参数和addLayersControl()函数联合使用,以增加网格显示开关。

1library(leaflet)

2

3#添加2种网格线,间距不一样,线宽不一样,颜色也不一样

4m%>%addGraticule(interval=30,

5style=list(color="#00ffff",weight=4),#="cyan"

6group="cyangrid")%>%

7addGraticule(interval=70,

8style=list(color="#ff00ff",weight=2),#="magenta"

9group="magentagrid")%>%

10addLayersControl(overlayGroups=c("cyangrid","magentagrid"),

11options=layersControlOptions(collapsed=FALSE))

12.3

Terminator (白天/黑夜指示器)

使用addTerminator()函数添加白天/黑夜指示器,划分区域。 白天黑夜跟时区没有关系,默认状态下,白天/黑夜指示器都是实时的。

并没有color,fillstyle等参数,所以不能调整颜色等设置。

1library(leaflet)

2

3#默认分辨率,阴影蒙板区域为黑夜

4leaflet()%>%addTiles()%>%addTerminator()

自定义分辨率和时区及时刻,然后添加到group开关中:

1library(leaflet)

2

3leaflet()%>%

4addTiles()%>%

5addTerminator(

6resolution=10,#指定分辨率,值越大,则精度越高,但计算量增加,默认为2

7time="-06-20T21:00:00Z",#时区及时刻

8group="day&light")%>%

9

10addLayersControl(

11overlayGroups="day&light",

12options=layersControlOptions(collapsed=FALSE))

12.4

Minimap小地图

可以使用addMinimap()函数添加一个坐标范围更大的小地图, 该功能同样是通过Leaflet-Minimap实现的。

注意,minimap上仅仅显示tiles, 不能显示markers, polygons等其它特征。

在小地图上可以缩放拖拽,大地图也会发生相应响应。

在大地图上缩放拖拽,小地图同样会响应。

小地图上有个矩形蒙板框,表示蒙板区域对应大地图上的边界。

1library(leaflet)

2

3l<-leaflet()%>%setView(0,0,3)

4

5l%>%addProviderTiles(providers$Esri.WorldStreetMap)%>%addMiniMap()

关键参数:

tiles, URL链接,指定小地图的tiles,可以与大地图不同。

toggleDisplay,为逻辑值,表示是否设置小地图开关,TRUE则出现箭头开关。

1library(leaflet)

2

3l%>%addProviderTiles(providers$Esri.WorldStreetMap)%>%addMiniMap(tiles=providers$Esri.WorldStreetMap,

4toggleDisplay=TRUE)

13.leafletCN(中国扩展包)

leafletCN是一个基于leaflet包做的大中华扩展,

优势在于有细分到县级市级别的区划数据, 虽然没那么准, 但是也基本能用了

leafletCN会自动匹配传入的前两个字符来寻找合适的位置进行绘制, 所以基本不需要纠结是写’上海市’还是’上海’了

常用函数:

regionNames()返回辖区内地名。

demomap()传入地名绘制辖区地图

geojsonMap()变量着色。

amap()叠加高德地图tiles

read.geoShape()读取一个geojson对象,保存成spdataframe, 以方便leaflet调用。

leafletGeo()用地图名以及一个数据框创建一个sp的对象。

13.1

regionNames()返回辖区名称

1library(leafletCN)

2

3regionNames("China")

4regionNames("四川省")

5regionNames("成都")

1##[1]"新疆维吾尔自治区""西藏自治区""内蒙古自治区"

2##[4]"青海省""四川省""黑龙江省"

3##[7]"甘肃省""云南省""广西壮族自治区"

4##[10]"湖南省""陕西省""广东省"

5##[13]"吉林省""河北省""湖北省"

6##[16]"贵州省""山东省""江西省"

7##[19]"河南省""辽宁省""山西省"

8##[22]"安徽省""福建省""浙江省"

9##[25]"江苏省""重庆市""宁夏回族自治区"

10##[28]"海南省""台湾省""北京市"

11##[31]"天津市""上海市""香港特别行政区"

12##[34]"澳门特别行政区"

13##[1]"甘孜藏族自治州""阿坝藏族羌族自治州""凉山彝族自治州"

14##[4]"绵阳市""达州市""广元市"

15##[7]"雅安市""宜宾市""乐山市"

16##[10]"南充市""巴中市""泸州市"

17##[13]"成都市""资阳市""攀枝花市"

18##[16]"眉山市""广安市""德阳市"

19##[19]"内江市""遂宁市""自贡市"

20##[1]"成华区""崇州市""大邑县""都江堰市""金牛区""金堂县"

21##[7]"锦江区""龙泉驿区""彭州市""蒲江县""青白江区""青羊区"

22##[13]"双流县""温江区""武侯区""新都区""新津县""邛崃市"

23##[19]"郫县"

13.2

demomap()返回辖区地图

1library(leafletCN)

2

3demomap("台湾")

13.3

geojsonmap()变量着色

1library(leaflet)

2library(leafletCN)

3

4dat<-data.frame(name=regionNames("china"),

5value=runif(34))

6geojsonMap(dat,"china")%>%#给变量value着色

7setView(lng=106.33,lat=29.35,zoom=3.5)

13.4

amap()叠加高德地图tiles

自带管道函数

1library(leaflet)

2library(leafletCN)

3

4leaflet()%>%amap()%>%addMarkers(lng=116.3125774825,lat=39.9707249401,

5popup="ThebirthplaceofCOS")

13.5

read.geoShape()读取geojson对象

1library(leaflet)

2library(leafletCN)

3

4if(require(sp)){

5filepath<-system.file("E:/R_input_output/data_input/JSON/GeoJSON/China.geojson",

6package="leafletCN")

7map<-read.geoShape(filepath)

8plot(map)

9}

13.6

leafletGeo()映射数据框

leafletGeo()这个函数可以把一个数据框和地图结合在一起,方便leaflet调用,

其中名字的变量为name, 数值的变量为value。

1library(leafletCN)

2

3if(require(leaflet)){

4dat=data.frame(regionNames("china"),runif(34))

5map=leafletGeo("china",dat)

6

7pal<-colorNumeric(palette="Blues",domain=map$value)

8

9leaflet(map)%>%addTiles()%>%addPolygons(stroke=TRUE,smoothFactor=1,

10fillOpacity=0.7,weight=1,color=~pal(value),popup=~htmltools::htmlEscape(popup))%>%

11addLegend("bottomright",pal=pal,values=~value,title="legendTitle",

12labFormat=leaflet::labelFormat(prefix=""),opacity=1)

13}

参考来源:

leaflet

(https://rstudio.github.io/leaflet/json.html)

geojson格式

(/p/5c6c6e76d4df)

leafletCN PPT

(/leafletIntro/Untitled.html#19)

R+大地图时代

(/sinat_26917383/article/details/57083985)

leafletCN github

(/lchiffon/leafletCN)

rgdal Tips

(/blog//01/13/tips-for-reading-spatial-files-into-r-with-rgdal/)

albersusa github

(/hrbrmstr/albersusa)

往期精彩:

R爬虫小白入门:Rvest爬链家网+分析(三)

“IT男等级”对照表|找找你在哪?

零基础:R必知必会

R语言中文社区终文章整理(作者篇)

R语言中文社区终文章整理(类型篇)

公众号后台回复关键字即可学习

回复爬虫爬虫三大案例实战

回复Python1小时破冰入门

回复数据挖掘R语言入门及数据挖掘

回复人工智能三个月入门人工智能

回复数据分析师数据分析师成长之路

回复机器学习机器学习的商业应用

回复数据科学数据科学实战

回复常用算法 常用数据挖掘算法

今天是妇女节

下班记得买束花送给自己的老婆和母亲↓

如果觉得《R_leaflet包_最易上手地图教程(二)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。