专栏名称: EasyCharts
EasyCharts,易图表,我们将定期推送各种数据可视化与分析教程,包括Excel(Power BI)、Origin、Sigmaplot、GraphPad、R、Python、Matlab、Tableau、D3.js等。
目录
相关文章推荐
前端大全  ·  前端行情变了,差别真的挺大。。。 ·  昨天  
前端大全  ·  真的建议所有前端立即拿下软考(红利期) ·  4 天前  
前端大全  ·  React+AI 技术栈(2025 版) ·  3 天前  
商务河北  ·  经开区“美•强•优”三重奏 ·  3 天前  
51好读  ›  专栏  ›  EasyCharts

R 最易上手地图教程(2):leaflet包

EasyCharts  · 公众号  · 前端  · 2019-09-02 23:29

正文

作者: 李誉辉

四川大学在读研究生


7.Colours着色

将变量映射到颜色是地理信息可视化的一个重要组成部分。
为了实现数值映射到颜色色值,leaflet中内置了一些
color* 开头的函数,
非常方便将数值变量与颜色进行匹配,然后产生一个palette函数。
这些palette函数, 能够根据输入数字向量返回一个 ARGB颜色空间 的向量。
ARGB颜色空间与HEX颜色空间类似,如“#AARRGGBB”中,前2个十六进制的数代表透明度,
后面三组数字分别代表Red, green, blue。具体见( https://coderwall.com/p/dedqca/argb-colors-in-android )。
leaflet 中有4个palette生成函数。

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

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

使用方法如下:

1library(leaflet)
2
3# 调动颜色函数,生成一个palette函数
4pal "red"
"green""blue"), 1:10)
5# 给色板函数传进一个数字向量,返回颜色色值向量。
6pal(c(169))


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


7.1

公共参数


4个颜色函数拥有几个公共参数: palette domain
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 
6# 结果一样
7China_map FALSE
)
8# China_map 
9Encoding(China_map@data$name) "UTF-8"
  # 纠正中文字符乱码
10
11# 编造GDP向量
12set.seed(234)
13values_fabricate 34, 0.10.9) * 2000  # 全国34个行政区
14China_map$GDP_fabricate NA)  # 经过China_map$name查询最后一个为占位
15
16map_draw % setView(lng = 106.33, lat = 29.35, zoom = 3.5)  # 以重庆城区经纬度为中心


1## OGR data source with driver: GeoJSON 
2## Source: "E:\R_input_output\data_input\JSON\TopoJson\China.json", layer: "中国"
3## with 35 features
4## It has 11 fields


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 "YlGnBu"
, domain = China_map$GDP_fabricate)
5
6map_draw %>% addPolygons(stroke = TRUE, smoothFactor = 0.3, fillOpacity = 0.8
7    color = ~Npal(GDP_fabricate))  # 默认fillColor = color



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

colorBin() 相当于对数据切片分箱,将数字性向量数据与固定数量的颜色输出相匹配。
可以通过指定breaks分割点来分箱,也可以指定分箱数来分箱,通过参数
bin
注意在按分箱数分箱时,如果
pretty = TRUE (默认),
将得到nice round的分割点,但是可能分箱数并不非你指定的。

1library(leaflet)
2
3Bpal "Blues"
, China_map$GDP_fabricate, 6, pretty = FALSE)
4
5map_draw %>% addPolygons(stroke = FALSE, smoothFactor = 0.2, fillOpacity = 1
6    color = ~Bpal(GDP_fabricate))


colorQuantile() 同样是对输入数据进行分箱,只是每个子集中的observation数量相等,
默认分成4个箱子,5个breaks。

1library(leaflet)
2
3Qpal "Blues"
, China_map$GDP_fabricate, n = 7)
4map_draw %>% addPolygons(stroke = FALSE, smoothFactor = 0.2, fillOpacity = 1
5    color = ~Qpal(GDP_fabricate))



7.3

类别型数据着色


对于类别型数据(categorical data), 使用 colorFactor() 函数生成色板函数。
如果palette包含的颜色数量与因子水平一致,则为一一对应匹配。
否则,palette中的颜色将会进行插值,然后产生合适数量的颜色。
可以通过给
domain 参数指定一个因子或字符串向量,或直接用 levels 参数指定因子水平。
levels 参数优先级比 domain 更高,如同时指定,则会忽略 domain 参数

 1




    
library(leaflet)
2
3# 生成一些随机levels
4China_map$category as
.factor(c(sample.int(5L, 34TRUE),NA))
5
6Fpal 5), China_map$category) # 因为是因子对象,第2个参数与levels参数匹配
7
8leaflet(China_map) %>% 
9  setView(lng = 106.33, lat = 29.35, zoom = 3.5) %>% # 以重庆城区经纬度为中心%>%
10  addPolygons(stroke = FALSE, smoothFactor = 0.2, fillOpacity = 1,
11    color = ~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 
6China_map  7# China_map 
8Encoding(China_map@data$name) "UTF-8"
 # 纠正中文字符乱码
9
10# 编造GDP向量
11set.seed(234)
12values_fabricate 34
0.10.9) * 2000 # 全国34个行政区
13China_map$GDP_fabricate # 经过China_map$name查询最后一个为占位
14
15map_draw % 
16  setView(lng = 106.33, lat = 29.35, zoom = 3.5)  # 以重庆城区经纬度为中心
17
18Npal "YlGnBu", domain = China_map$GDP_fabricate)
19
20map_draw %>%
21   addPolygons(stroke = FALSE, smoothFactor = 0.2, fillOpacity = 1,
22    color = ~Npal(GDP_fabricate)) %>%
23
24  addLegend("bottomright", pal = Npal, values = ~GDP_fabricate, # 生成图例
25    title = "China.GDP(fabricate)"# 图例标题
26    labFormat = labelFormat(prefix = "¥", suffix = "(亿元)"), # 标签增加前缀后缀
27    opacity = 1)



addLegend() 函数与palette函数的类型有关,
对不同类型的palette,会生成不同形式的图例。
比较上图中基于
colorNumeric() 函数生成的图例,
与下图中基于
colorQuantile() 生成的图例,可以发现:
后者显示大概范围,图例刻度标签也不同。


1library(leaflet)
2
3Qpal "RdYlBu"
, China_map$GDP_fabricate, n = 5reverse = TRUE)  # 分位数分箱,5等分,reverse = TRUE翻转颜色
4map_draw %>% addPolygons(stroke = FALSE, smoothFactor = 0.2, fillOpacity = 1
5    color = ~Qpal(GDP_fabricate)) %>% addLegend(pal = Qpal, values = ~GDP_fabricate, 
6    opacity = 1)



addLegend() 还有其它几个参数,使得能够以多种方式定制图例,
还有
colors labels 参数,具体指定可以定制与大图不一样颜色和标签图例。 还可以定制图例标题和 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() %>%
4  addTiles() %>%
5  addMarkers(data = coffee_shops, group = "Food & Drink") %>% # 指定group参数
6  addMarkers(data = restaurants, group = "Food & Drink") %>%
7  addMarkers(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 long
, quakes$lat), ]  # 索引子数据框
5
6map % # 设置basegroup
7addTiles(group = "OSM (default)") %>% addProviderTiles(providers$Stamen.Toner, 
8    group = "Toner") %>% addProviderTiles(providers$Stamen.TonerLite, group = "Toner Lite") %>% 
9    # 设置Overlay groups
10addCircles(~long, ~lat, ~10^mag/5, stroke = F, group = "Quakes") %>% addPolygons(data = outline, 
11    lng = ~long, lat = ~lat, fill = F, weight = 2, color = "#FFFFCC"group = "Outline") %>% 
12
13# 设置layers切换
14addLayersControl(baseGroups = c("OSM (default)""Toner""Toner Lite"), 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 %
4  #  mutate列运算,产生新列,新列名为mag.level
5  dplyr::mutate(mag.level = cut(mag,c(3,4,5,6),  # 分箱,breaks为3,4,5,6。 
6                                labels = c('>3 & <=4''>4 & <=5' '>5 & <=6')))
7
8quakes.df # 将quakes根据mag.level分组,变成3个元素的列表

9
10l % addTiles()
11
12names(quakes.df) %>%
13  purrr::walk( function(df) # walk迭代,
14    l <% # 深度赋值,l会变成全局变量
15      addMarkers(data=quakes.df[[df]], # 闭包索引
16                 lng=~long, lat=~lat,
17                 label=~as.character(mag),
18                 popup=~as.character(mag),
19                 group = df,
20                 clusterOptions = markerClusterOptions(removeOutsideVisibleBounds = F),
21                 labelOptions = labelOptions(noHide = F,direction = 'auto'))
22  })
23
24l %>%
25  addLayersControl(
26    overlayGroups = names(quakes.df),
27    options = layersControlOptions(collapsed = FALSE)
28  )


walk 函数

https://d-rug.github.io/images/20171026/20171023_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 
6# 结果一样
7China_map FALSE
)
8# China_map 
9Encoding(China_map@data$name) "UTF-8"
  # 纠正中文字符乱码
10
11 # 编造GDP向量
12set.seed(234)
13values_fabricate 34, 0.10.9) * 2000  # 全国34个行政区
14China_map$GDP_fabricate NA)  # 经过China_map$name查询最后一个为占位
15
16map_draw % setView(lng = 106.33, lat = 29.35, zoom = 3.5)  # 以重庆城区经纬度为中心


1## OGR data source with driver: GeoJSON 
2## Source: "E:\R_input_output\data_input\JSON\TopoJson\China.json", layer: "中国"
3## with 35 features
4## It has 11 fields



10.2

底图着色


 1library(leaflet)
2
3# 通过手动分箱添加颜色,这样就不是等分
4bins 200
500800120015001800# 分箱的分割点
5Bpal "YlOrRd", domain = China_map$GDP_fabricate, 
6                 bins = bins) # 通过分箱生成palette函数
7
8map_draw %>%
9  addPolygons(stroke = TRUE, smoothFactor = 0.2
10              fillOpacity = 0.7,
11              fillColor = ~Bpal(GDP_fabricate),
12              weight = 2,
13              opacity = 1,
14              color = "lime",
15              dashArray = "3") %>%
16
17  addLegend("bottomright", pal = Bpal, values = ~GDP_fabricate, # 生成图例
18    title = "China.GDP(fabricate)"# 图例标题
19    labFormat = labelFormat(prefix = "¥", suffix = "(亿元)"), # 标签增加前缀后缀
20    opacity = 1)




10.3

区域高亮


接下来给地图多边形增加交互性,要求当鼠标掠过多边形上时,多边形会高亮。
即在
addPolygons() 内设置高亮参数 highlight

 1library(leaflet)
2
3map_draw %>%
4  addPolygons(stroke = TRUE, smoothFactor = 0.2
5              fillOpacity = 0.7,
6              fillColor = ~Bpal(GDP_fabricate),
7              weight = 2,
8              opacity = 1,
9              color = "lime",
10              dashArray = "3",
11              highlight = highlightOptions(#  增加高亮参数
12                weight = 5,
13                color = "cyan",
14                dashArray = "",
15                fillOpacity = 0.3,
16                bringToFront = TRUE)
17              ) %>%
18
19  addLegend("bottomright", pal = Bpal, values = ~GDP_fabricate, # 生成图例
20    title = "China.GDP(fabricate)"# 图例标题
21    labFormat = labelFormat(prefix = "¥", suffix = "(亿元)"), # 标签增加前缀后缀
22    opacity = 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  "%s
%g people / m2"
# HTML语法,
表示换行符,

6  China_map$name, China_map$GDP_fabricate
7) %>% 
8
9  lapply(htmltools::HTML) # 对向量labels中每个元素进行了HTML处理,全当作HTML处理
10
11map_draw_2 % 
12  addPolygons(
13    stroke = TRUE, smoothFactor = 0.2
14    fillOpacity = 0.7,
15    fillColor = ~Bpal(GDP_fabricate),
16    weight = 2,
17    opacity = 1,
18    color = "lime",
19    dashArray = "3",
20    highlight = highlightOptions(#  增加高亮参数
21      weight = 5,
22      color = "cyan",
23      dashArray = "",
24      fillOpacity = 0.3,
25      bringToFront = TRUE),
26    label = labels,
27    labelOptions = labelOptions(
28      style = list("font-weight" = "normal", padding = "3px 8px"),
29      textsize = "15px",
30      direction = "auto"))%>%
31
32  addLegend("bottomright", pal = Bpal, values = ~GDP_fabricate, # 生成图例
33    title = "China.GDP(fabricate)"# 图例标题
34    labFormat = labelFormat(prefix = "¥", suffix = "(亿元)"), # 标签增加前缀后缀
35    opacity = 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( https://github.com/kartena/Proj4Leaflet )插件。
这使
leaflet 在理论上可以访问Proj4js( http://proj4js.org/ )支持的任何CRS

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


11.1

自定义CRS


一旦你决定要自定义一个CRS了,并且有能与之匹配的tiles。
那么你可以使用
leafletCRS() 来自定义一个CRS。

1library(leaflet)
2
3crs "L.Proj.CRS"
, code = "ESRI:102003", 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"
4    resolutions = 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/ )或spatialreference.org( http://spatialreference.org/ )中找到需要的字符串。

通过参数 crs = leafletOptions(crs = ...). ,
可以将
leafletCRS() 产生的对象传递给 leaflet() 函数。


11.2

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


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

 1library(leaflet)
2
3# 自定义CRS投影坐标系
4epsg3006 "L.Proj.CRS"
, code = "EPSG:3006",
5  proj4def = "+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs",
6  resolutions = 2^(13:-1), # 设置分辨率,每个像素点代表多少米,用于缩放,从 8192到0.5
7  origin = c(00# 原点坐标
8 )
9
10tile_url "http://api.geosition.com/tile/osm-bright-3006/{z}/{x}/{y}.png"
11tile_attrib "Map data © OpenStreetMap contributors, Imagery © 2013 Kartena"
12
13# 绘widget图
14leaflet(options = leafletOptions(worldCopyJump = F, crs = epsg3006)) %>% # 指定crs参数
15  setView(11.96505357.7045113) %>%
16  addTiles(urlTemplate = t
ile_url, # 使用URL上的模板
17    attribution = tile_attrib, # widget下面的小字,表示tiles layer的属性,为HTML语法
18    options = tileOptions(minZoom = 0, maxZoom = 14, continuousWorld = T)) %>%
19  addMarkers(11.96505357.70451)



再次强调,学会使用
leafletCRS() 函数自定义CRS,
并基于该CRS投影坐标系添加tiles底图,非常重要。
事实上,上图中,来自api.geosition.com 服务商的tiles正是基于EPSG:3006产生的。
我们可以通过使用默认的EPSG:3857来绘制一个类似的地图,与上图进行比较。
如果自定义的CRS正常工作,则marker会出现在相同的位置:

1library(leaflet)
2
3leaflet() %>% setView(11.965053, 57.70451, 16) %>% addTiles() %>% addMarkers(11.965053
4    57.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 0.1
# 简化polygons数据集
6
7pal "Blues", domain = spdf$pop_2014) # 产生palette函数
8
9# 自定义CRS
10epsg2163 11  crsClass = "L.Proj.CRS",
12  code = "EPSG:2163",
13  proj4def = "+proj=laea +lat_0=45 +lon_0=-100 +x_0=0 +y_0=0 +a=6370997 +b=6370997 +units=m +no_defs",
14  resolutions = 2^(16:7)) # 设置分辨率,每个像素代表多少米,用于缩放
15
16# 基于CRS坐标系和spdf数据集,绘制地图
17leaflet(spdf, options = leafletOptions(crs = epsg2163)) %>% # 使用自定义的CRS
18  addPolygons(weight = 1, color = "#444444", opacity = 1# 设置边界线线宽,颜色,透明度
19    fillColor = ~pal(pop_2014), fillOpacity = 0.7
20    smoothFactor = 0.5,
21    label = ~paste(name, pop_2014),
22    labelOptions = labelOptions(direction = "auto"))



11.4

极地投影坐标系


有时候也会需要使用极地投影坐标系,
相比其它投影坐标系,可能会遇到更多的问题,甚至与其它Leaflet.js插件不兼容性问题。
可以参考的 Bhaskar Karambelkar的案例

( http://rpubs.com/bhaskarvk/leaflet-polarmaps )


12.附加特征


常用附加特征包括:

  • leaflet Measure(刻度尺)

  • Graticule(网格线)

  • Terminator(白天黑夜指示器)

  • Minimap(小地图)


12.1

Leaflet Measure 刻度尺


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

https://github.com/ljagis/leaflet-measure
刻度尺使用方法:

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

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

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

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

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

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


1library(leaflet)
2
3m <- leaflet() %>% addTiles ()
4
5m %>%
6  fitBounds(-73.9, 40.75-73.95,40.8) %>% #fitBounds设定地图矩形区域边界,定到纽约中央公园
7  addMeasure() # 添加刻度尺插件,默认位置在widget右上角



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

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

  • primaryLengthUnit , 表示指定 测量长度时 显示的主要长度单位,
    主要长度后面的括号内为可选参数,表示次要长度单位
    secondaryLengthUnit

  • primaryAreaUnit , 表示指定 测量面积时 显示的主要长度单位,
    同样括号内为次要面积单位
    secondaryAreaUnit

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

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

 1library(leaflet)
2
3m %>%
4  fitBounds(13.7613452.67549913.088452.33812) %>% # 设定边界到德国柏林
5  addMeasure(
6    position = "bottomleft"# 设定刻度尺相对位置为左下角
7    primaryLengthUnit = "meters"# 设定测量长度时显示的主要长度单位
8    primaryAreaUnit = "sqmeters"# 设定测量面积时显示的主要面积单位
9    activeColor = "#00ffff"# = cyan, 激活刻度尺时,点线面的颜色。
10    completedColor = "#ff00ff"# = magenta, 表示Finish测量后,点线面的颜色。




12.2

Graticule网格线


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

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

  • style , 表示网格线的样式, 列表传参
    可以设定网格线线型
    dashArray ,线宽 weight ,颜色 color ,透明度 Opacity 等。

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


1library(leaflet)
2
3<- leaflet() %>% addTiles() %>% setView(0, 0, 2)
4m %>% addGraticule()



1library(leaflet)
2# 添加2种网格线,间距不一样,线宽不一样,颜色也不一样
3m %>% addGraticule(interval = 30
4                   style = list(color = "#00ffff", weight = 4)) %>% # = "cyan"
5 addGraticule(interval = 70, style = list(color = "#ff00ff", weight = 2)) # = "magenta"



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

 1library(leaflet)
2
3# 添加2种网格线,间距不一样,线宽不一样,颜色也不一样
4m %>% addGraticule(interval = 30
5                   style = list(color = "#00ffff", weight = 4),# = "cyan"
6                   group = "cyan grid") %>% 
7 addGraticule(interval = 70
8              style = list(color = "#ff00ff", weight = 2),# = "magenta"
9              group = "magenta grid") %>%
10 addLayersControl(overlayGroups = c("cyan grid""magenta grid"),
11    options = layersControlOptions(collapsed = FALSE))








请到「今天看啥」查看全文