作者:李誉辉

四川大学在读研究生

这次,我们接着上一篇讲

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)23# 调动颜色函数,生成一个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"  # 纠正中文字符乱码1011# 编造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查询最后一个为占位1516map_draw <- leaflet(China_map) %>% 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 features4## 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)34Npal <- colorNumeric(palette = "YlGnBu", domain = China_map$GDP_fabricate)56map_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)23Bpal <- colorBin(palette = "Blues", China_map$GDP_fabricate, 6, pretty = FALSE)45map_draw %>% addPolygons(stroke = FALSE, smoothFactor = 0.2, fillOpacity = 1, 6    color = ~Bpal(GDP_fabricate))

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

1library(leaflet)23Qpal <- colorQuantile("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参数

 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) %>%  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 <- "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" # 纠正中文字符乱码 910# 编造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查询最后一个为占位1415map_draw <- leaflet(China_map) %>% 16  setView(lng = 106.33, lat = 29.35, zoom = 3.5)  # 以重庆城区经纬度为中心1718Npal <- colorNumeric(palette = "YlGnBu", domain = China_map$GDP_fabricate)1920map_draw %>%21  addPolygons(stroke = FALSE, smoothFactor = 0.2, fillOpacity = 1,22    color = ~Npal(GDP_fabricate)) %>%2324  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)23Qpal <- colorQuantile("RdYlBu", China_map$GDP_fabricate, n = 5, reverse = 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()还有其它几个参数,使得能够以多种方式定制图例,
还有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)23leaflet() %>%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 <- quakes[chull(quakes$long, quakes$lat), ]  # 索引子数据框 5 6map <- leaflet(quakes) %>% # 设置basegroup 7addTiles(group = "OSM (default)") %>% addProviderTiles(providers$Stamen.Toner,  8    group = "Toner") %>% addProviderTiles(providers$Stamen.TonerLite, group = "Toner Lite") %>%  9    # 设置Overlay groups10addCircles(~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") %>% 1213# 设置layers切换14addLayersControl(baseGroups = c("OSM (default)", "Toner", "Toner Lite"), overlayGroups = c("Quakes", 15    "Outline"), options = layersControlOptions(collapsed = FALSE))1617map

9.3

图标簇分组

如果将markers clusters图标簇分成不同的group组。
当按照marker小节中那样添加markers时,
leaflet就能根据group将markers分成不同的簇了。 这样就能设定不同组别的图标簇显示/隐藏了。

 1library(leaflet) 2 3quakes <- quakes %>% 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 <- split(quakes, quakes$mag.level) # 将quakes根据mag.level分组,变成3个元素的列表 910l <- leaflet() %>% addTiles()1112names(quakes.df) %>%13  purrr::walk( function(df) { # walk迭代,14    l <<- 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  })2324l %>%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 <- '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"  # 纠正中文字符乱码1011# 编造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查询最后一个为占位1516map_draw <- leaflet(China_map) %>% 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 features4## It has 11 fields

10.2

底图着色

 1library(leaflet) 2 3# 通过手动分箱添加颜色,这样就不是等分 4bins <- c(200, 500, 800, 1200, 1500, 1800) # 分箱的分割点 5Bpal <- colorBin("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") %>%1617  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              ) %>%1819  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  "<strong>%s</strong><br/>%g people / m<sup>2</sup>", # HTML语法,<br/>表示换行符, 6  China_map$name, China_map$GDP_fabricate 7) %>%  8 9  lapply(htmltools::HTML) # 对向量labels中每个元素进行了HTML处理,全当作HTML处理1011map_draw_2 <- map_draw %>% 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"))%>%3132  addLegend("bottomright", pal = Bpal, values = ~GDP_fabricate, # 生成图例33    title = "China.GDP(fabricate)", # 图例标题34    labFormat = labelFormat(prefix = "¥", suffix = "(亿元)"), # 标签增加前缀后缀35    opacity = 1)3637map_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)23crs <- leafletCRS(crsClass = "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 <- leafletCRS(crsClass = "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(0, 0) # 原点坐标 8) 910tile_url <- "http://api.geosition.com/tile/osm-bright-3006/{z}/{x}/{y}.png"11tile_attrib <- "Map data &copy; <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap contributors</a>, Imagery &copy; 2013 <a href='http://www.kartena.se/'>Kartena</a>"1213# 绘widget图14leaflet(options = leafletOptions(worldCopyJump = F, crs = epsg3006)) %>% # 指定crs参数15  setView(11.965053, 57.70451, 13) %>%16  addTiles(urlTemplate = tile_url, # 使用URL上的模板17    attribution = tile_attrib, # widget下面的小字,表示tiles layer的属性,为HTML语法18    options = tileOptions(minZoom = 0, maxZoom = 14, continuousWorld = T)) %>%19  addMarkers(11.965053, 57.70451)

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

1library(leaflet)23leaflet() %>% 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 <- rmapshaper::ms_simplify(usa_sf(), keep = 0.1) # 简化polygons数据集 6 7pal <- colorNumeric("Blues", domain = spdf$pop_2014) # 产生palette函数 8 9# 自定义CRS10epsg2163 <- leafletCRS(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)) # 设置分辨率,每个像素代表多少米,用于缩放1516# 基于CRS坐标系和spdf数据集,绘制地图17leaflet(spdf, options = leafletOptions(crs = epsg2163)) %>% # 使用自定义的CRS18  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)23m <- leaflet() %>% addTiles()45m %>%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.76134, 52.675499, 13.0884, 52.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等。

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

1library(leaflet)23m <- 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))

12.3

Terminator (白天/黑夜指示器)

使用addTerminator()函数添加白天/黑夜指示器,划分区域。 白天黑夜跟时区没有关系,默认状态下,白天/黑夜指示器都是实时的。
并没有color,fillstyle等参数,所以不能调整颜色等设置。

1library(leaflet)23# 默认分辨率,阴影蒙板区域为黑夜4leaflet() %>% addTiles() %>% addTerminator()

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

 1library(leaflet) 2 3leaflet() %>% 4  addTiles() %>% 5  addTerminator( 6    resolution=10, # 指定分辨率,值越大,则精度越高,但计算量增加,默认为2 7    time = "2013-06-20T21:00:00Z", # 时区及时刻 8    group = "day&light") %>% 910  addLayersControl(11    overlayGroups = "day&light",12    options = layersControlOptions(collapsed = FALSE))

12.4

Minimap小地图

可以使用addMinimap()函数添加一个坐标范围更大的小地图, 该功能同样是通过Leaflet-Minimap实现的。
注意,minimap上仅仅显示tiles, 不能显示markers, polygons等其它特征。
在小地图上可以缩放拖拽,大地图也会发生相应响应。
在大地图上缩放拖拽,小地图同样会响应。
小地图上有个矩形蒙板框,表示蒙板区域对应大地图上的边界。

1library(leaflet)23l <- leaflet() %>% setView(0, 0, 3)45l %>% addProviderTiles(providers$Esri.WorldStreetMap) %>% addMiniMap()

关键参数:

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

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

1library(leaflet)23l %>% addProviderTiles(providers$Esri.WorldStreetMap) %>% addMiniMap(tiles = providers$Esri.WorldStreetMap, 4    toggleDisplay = TRUE)

13.leafletCN(中国扩展包)

leafletCN是一个基于leaflet包做的大中华扩展,
优势在于有细分到县级市级别的区划数据, 虽然没那么准, 但是也基本能用了
leafletCN会自动匹配传入的前两个字符来寻找合适的位置进行绘制, 所以基本不需要纠结是写’上海市’还是’上海’了
常用函数:

  • regionNames()返回辖区内地名。

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

  • geojsonMap()变量着色。

  • amap()叠加高德地图tiles

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

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

13.1

regionNames()返回辖区名称

1library(leafletCN)23regionNames("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)23demomap("台湾")

13.3

geojsonmap()变量着色

1library(leaflet)2library(leafletCN)34dat <-  data.frame(name = regionNames("china"),5                 value = runif(34))6geojsonMap(dat,"china") %>%  # 给变量value着色7  setView(lng = 106.33, lat = 29.35, zoom = 3.5)

13.4

amap()叠加高德地图tiles

自带管道函数

1library(leaflet)2library(leafletCN)34leaflet() %>% amap() %>% addMarkers(lng = 116.3125774825, lat = 39.9707249401, 5    popup = "The birthplace of COS")

13.5

read.geoShape()读取geojson对象

1library(leaflet)2library(leafletCN)34if (require(sp)) {5    filepath <- system.file("E:/R_input_output/data_input/JSON/GeoJSON/China.geojson", 6        package = "leafletCN")7    map <- read.geoShape(filepath)8    plot(map)9}

13.6

leafletGeo()映射数据框

leafletGeo()这个函数可以把一个数据框和地图结合在一起,方便leaflet调用,
其中名字的变量为name, 数值的变量为value。

 1library(leafletCN) 2 3if (require(leaflet)) { 4    dat = data.frame(regionNames("china"), runif(34)) 5    map = leafletGeo("china", dat) 6 7    pal <- colorNumeric(palette = "Blues", domain = map$value) 8 9    leaflet(map) %>% addTiles() %>% addPolygons(stroke = TRUE, smoothFactor = 1, 10        fillOpacity = 0.7, weight = 1, color = ~pal(value), popup = ~htmltools::htmlEscape(popup)) %>% 11        addLegend("bottomright", pal = pal, values = ~value, title = "legendTitle", 12            labFormat = leaflet::labelFormat(prefix = ""), opacity = 1)13}


参考来源:

  • leaflet

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

  • geojson格式

(https://www.jianshu.com/p/5c6c6e76d4df)

  • leafletCN PPT

(http://langdawei.com/leafletIntro/Untitled.html#19)

  • R+大地图时代

(https://blog.csdn.net/sinat_26917383/article/details/57083985)

  • leafletCN github

(https://github.com/lchiffon/leafletCN)

  • rgdal Tips

(http://zevross.com/blog/2016/01/13/tips-for-reading-spatial-files-into-r-with-rgdal/)

  • albersusa github

(https://github.com/hrbrmstr/albersusa)

往期精彩:

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

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

  • 零基础:R必知必会

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

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

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

回复 爬虫            爬虫三大案例实战
回复 Python       1小时破冰入门
回复 数据挖掘     R语言入门及数据挖掘
回复 人工智能     三个月入门人工智能
回复 数据分析师  数据分析师成长之路 
回复 机器学习     机器学习的商业应用
回复 数据科学     数据科学实战
回复 常用算法     常用数据挖掘算法

今天是妇女节

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

R_leaflet包_最易上手地图教程(二)相关推荐

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

    欢迎关注天善智能,我们是专注于商业智能BI,人工智能AI,大数据分析与挖掘领域的垂直社区,学习,问答.求职一站式搞定! 对商业智能BI.大数据分析挖掘.机器学习,python,R等数据领域感兴趣的同学 ...

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

    作者:李誉辉 四川大学在读研究生 简 介

  3. 战地2服务器2地图修改,【战地2怎么将地图改为32人】如何修改地图_战地2修改地图教程_游戏城...

    问:<战地2>怎么将地图改为32人? 答:修改教程如下: 将地图大小更换为32/64大小的方法,我已经参考外国的修改法,成功的改出! 但请注意,本方法只是成功的将地图改出来,针对AI的路径 ...

  4. 魅族pro5 刷机 android,魅族Pro5线刷救砖ROM包_线刷救砖教程

    三:使用魅族MTK刷机工具刷机步骤详解 一.安装驱动 1.双击打开[手机驱动]文件 2.弹出如下窗口,点击[是] 3.点击[下一步]安装 4.勾选[始终信任来自"Invisibility L ...

  5. 手工做迷宫_好玩易上手的自然探索实验,春天必备,宅家就能带孩子做起来!...

    春天到了,春风轻拂,花苞含笑,柳梢鹅黄.不过这个春天比较特别,没有太多机会把"神兽"放归大自然,多数时间得宅在家中守候着平安. 憨弟给大家分享两个很有意思的自然探索实验,取材非常简 ...

  6. python飞机大战源码素材包_小甲鱼python基础教程飞机大战源码及素材

    原博文 2018-12-22 23:32 − 百度了半天小甲鱼python飞机大战的源码和素材,搜出一堆不知道是什么玩意儿的玩意儿. 最终还是自己对着视频一行行代码敲出来. 需要的同学点下面的链接自取 ...

  7. 简单绘图软件实现mfc大作业_生产流程图怎么做?简单易上手的流程图工具

    生产流程图是什么呢?首先,生产流程指的是在生产的过程中,劳动者通过利用一定的生产设备或工具,将各种原材料.半成品投入,按照一定顺序进行加工,最终得到成品产出的整个过程.而生产流程图则是使用图表符号的形 ...

  8. 蓝牙驱动卸载后自动安装_最热建筑安装工程计算表格,输入后自动生成,省时方便易上手...

    最热建筑安装工程计算表格,输入后自动生成,省时方便易上手! 工程量计算是每一个造价从业者必备技能.但是要保证计算过程中不能有一丝丝差错,实在是一件令人头疼的事情,因为步骤比较繁杂,并且算量大,一不小心 ...

  9. 本行没有输入值结余隐藏_仓库库存管理系统,内含逻辑公式,自动结余库存!操作简单易上手...

    仓库库存管理系统,内含逻辑公式,自动结余库存!操作简单易上手 仓库出入库管理系统 入库单 出入库单号自动生成,如需修改前缀,可根据提示自行修改.在设置中,根据实际情况对必须填写的项输入,方便后期可自动 ...

  10. 小米MIX线刷兼救砖_解账户锁_纯净刷机包_教程

    确保你的手机已经解BL锁了,如果没有解BL锁的话 查看教程 手机先关机,并且手机先不要用数据线连接电脑,先断开数据线. 一:下载刷机包并解压 点击下载 二:打开rom文件夹里找到<Fastboo ...

最新文章

  1. 刻意练习:LeetCode实战 -- Task09. 环形链表
  2. 最优化评分法c语言,最优化方法及其实现(Optimization-Algorithm)C语言
  3. 计算机技术应用体验,信息技术应用体验学习心得体会
  4. [react] 举例说明什么是高阶组件(HOC)的反向继承
  5. 程序语言python如何抓取信息_python中系统信息获取psutil使用详解
  6. android ffmpeg编译动态库,最简单的android studio调用ffmpeg动态库
  7. SHELL中的变量和参数
  8. CCF201809-4 再卖菜(100分)【DFS】
  9. AJAX框架都有哪些是常用的
  10. 解决DOS窗口中文乱码问题
  11. 软件工程系统建模总结
  12. Windows10 电脑蓝屏方案对照表
  13. 微服务与敏捷开发(Scrum/Kanban)的核心思想之我见
  14. 丢番图生平编程java_丢番图
  15. W: 校验数字签名时出错。此仓库未被更新,所以仍然使用此前的索引文件。
  16. sed编辑器之删除行
  17. sqlServer 身份认证 登录
  18. 【Unity3D插件】AVPro Video2.x rtmp流媒体播放设置问题
  19. UVA 1218 完美的服务
  20. C语言编程>第十八周 ⑧ 给定程序中,函数fun的功能是:将形参指针所指结构体数组中的三个元素按num成员进行升序排列。

热门文章

  1. 【运筹学】整数规划、分支定界法总结 ( 整数规划 | 分支定界法 | 整数规划问题 | 松弛问题 | 分支定界法 | 分支定界法概念 | 分支定界法步骤 ) ★★
  2. 软件系统设计-12-软件设计体系结构概述
  3. 电脑连接校园网不自动跳转到登录界面
  4. 易语言:游戏辅助 CF队伤“卡秒器“ 编程思路/开发者优化建议
  5. cnplaza照片打印管理 【即影即有软件】
  6. python数字字母识别_字符图像识别——数字字母混合
  7. 磁滞回线与软磁材料和硬磁材料的关系
  8. matlab读取多张图片数据
  9. 高淇300集Java——零基础开发桌球小游戏项目
  10. idea创建VUE项目