R-ggspatial+ggplot2 实现带指北针和比例尺的空间地图绘制

2021-02-22 15:02:36 浏览数 (2)

继上次使用tmap包制作含有指北针(compass)和比例尺(scale bar)以及南海小地图的添加,详细内容分别见如下两篇文章:R-tmap 绘制带指北针和比例尺的空间地图和 R-tmap grid 实现南海小地图的添加,得到了很多小伙伴的喜欢。虽然tmap包有着类似于ggplot2绘图语法,但对习惯使用ggplot2绘图的小伙伴怎不怎么友好。那么今天本期推文就使用 ggspatial 包实现指北针和比例尺的添加。主要涉及的知识点如下:

  • sf包shp文件读取及转换投影
  • ggplot2 ggspatial 实现指北针和比例尺的添加

sf 读取shp文件并转换投影

我想经常使用R处理空间数据的小伙伴们对sf包一定特别熟悉,本期推文只涉及shp文件的读取和坐标转换,更多sf内容可参看官网描述sf官网。

shp文件读取

代码语言:javascript复制
library(sf)
library(here)
library(tidyverse)
library(ggspatial)

china <- 'E:/china.shp'
china_pro <- sf::read_sf(china)
nine <- 'E:/china_nine_dotted_line.shp'
nine_line <- sf::read_sf(nine)

以上代码即可实现对shp文件的读取,操作也十分方便,顺便提一下,现在大部分用于可视化空间数据的R包都是支持sf文件格式的哦。

可视化展示

如果只是出图,那代码就非常简便:

代码语言:javascript复制
china_province <- ggplot()  
       geom_sf(data = china_pro)  
       geom_sf(data = nine_line)
china_province

可视化结果如下:

ggspatial 添加指北针和比例尺

我们使用ggspatial包的annotation_scale()和annotation_north_arrow()方法实现这两个重要地图要素的添加。具体代码如下:

代码语言:javascript复制
library(ggspatial)
china_province_gg <- ggplot()  
       geom_sf(data = china_pro)  
       geom_sf(data = nine_line)  
       annotation_scale(location = "bl")  
      # spatial-aware automagic north arrow
       annotation_north_arrow(location = "tl", which_north = "true",
                             style = north_arrow_fancy_orienteering) 
       labs(x ='Longitude',y="Latitude",
       title = "Scale bar and North arrow Test",
       subtitle = "ggspatial make",
       caption = 'Visualization by DataCharm')
china_province_gg

可视化结果如下:

当然指北针和比例尺我们都是可以选择样式或者定制的,详细内容可以查看网ggspatial官网

投影转换-高斯-克吕格投影

绘制中国地图时,我们一般使用高斯-克吕格投影,具体原因如下:高斯-克吕格投影没有角度变形,在长度和面积上变形也很小,中央经线无变形,自中央经线向投影带边缘,变形逐渐增加,变形最大处在投影带内赤道的两端。由于其投影精度高,变形小,而且计算简便(各投影带坐标一致,只要算出一个带的数据,其他各带都能应用),因此在大比例尺地形图中应用,可以满足军事上各种需要,并能在图上进行精确的量测计算(来源于百度)。而sf对于投影转换操作也十分简单,代码如下即可:

代码语言:javascript复制
china_shp_pro <- st_transform(china_pro, 2343)
nine_line_pro <- st_transform(nine_line, 2343)

我们在此基础上再进行可视化展示,此外,我们设置了如:主题样式、字体等操作。这里提一下:有的小伙伴说R添加字体比较麻烦,我是这么添加的:

代码语言:javascript复制
#添加字体
windowsFonts(
   Cinzel = windowsFont("Cinzel"),#这里使用的是字体的主题名称
   Poppins = windowsFont("Poppins"),
   IBMPSBold = windowsFont("IBMPlexSans-Bold"),
   Roboto_Mono = windowsFont("Roboto Mono"),
   Open_Sans = windowsFont("Open Sans"),
   Open_Sans_ExtraBold = windowsFont("Open Sans ExtraBold"),
   Times_New_Roman = windowsFont("Times New Roman")
  )

大家可以参考下。回到这里,绘制高斯-克吕格投影的地图:

代码语言:javascript复制
china_shp_pro <- st_transform(china_pro, 2343)
nine_line_pro <- st_transform(nine_line, 2343)

china_map_pro <- ggplot()  
       geom_sf(data = china_shp_pro) 
       geom_sf(data = nine_line_pro) 
       annotation_scale(location = "bl")  
#        annotation_north_arrow(location = "tl",which_north = "true",
#                              style = north_arrow_fancy_orienteering)
       annotation_north_arrow(location = "tl",
                             style = north_arrow_fancy_orienteering) 
       labs(x ='Longitude',y="Latitude",
       title = "Scale bar and North arrow Test",
       subtitle = "ggspatial make 2343",
       caption = 'Visualization by DataCharm') 
       theme_bw() 
       theme(text = element_text(family = "Times_New_Roman",face='bold'),
           axis.text = element_text(family = 'Times_New_Roman',size = 14,face = 'bold'),
           axis.title.x = element_text(family = 'Times_New_Roman',size = 16,face = 'bold'),
           axis.title.y = element_text(family = 'Times_New_Roman',size = 16,face = 'bold'),
           #修改刻度线内
           axis.ticks.length=unit(0.2, "cm"), 
           #加宽图边框
           #panel.border = element_rect(size=1),
           plot.background = element_rect(color = "white"),
          # axis.line = element_line(size = .8),
           axis.ticks = element_line(size = .8))
china_map_pro

最终的可视化结果如下:

这里注意下图中指北针的方向(图中圆圈标出),这是因为我们在添加指北针的语句:annotation_north_arrow() 设置了which_north = "true" ,如果不设置,就会和第一幅图一样,大家可以注意下

总结

本期推文我们使用ggspatial包、ggplot2包以及sf包的geom_sf()完成另一种指北针和比例尺地图的绘制,希望给大家一些绘制灵感。(至于有的小伙伴会问“为啥没南海小地图添加的绘制脚本呢?”这个吗?大家可以先考虑下,后面我再出教程推文,不说了,要锻炼了

0 人点赞