sf | 读取和保存空间矢量数据

R语言储存矢量数据(.shp)目前有两种规范:

第一种规范来自sp工具包,数据以Spatial*DataFrame形式储存,执行的标准来自Esri shapefile的相关方法,其定义的数据结构与R中基本的数据结构有着较大的区别。它更多的关注数据中的空间信息,数据结构比较复杂。这种数据格式要素类型又可细分为如下几类:

  • SpatialPointsDataFrame

  • SpatialLinesDataFrame

  • SpatialPolygonsDataFrame

  • ....

第二种规范来自sf工具包,它制定了一种新的储存空间数据的标准,是将空间数据中每个要素看做是一个simple feature,数据结构按照要素展开,每个要素信息单独占一行,其属性数据分别对应各列,而空间信息也作为一种属性占据一列。这样从外观上看,空间数据与R中普通的数据框(data.frame)并无太大区别,使得数据结构比较清晰。

图片地址:https://mirrors.tuna.tsinghua.edu.cn/CRAN/web/packages/sf/vignettes/sf1.html


1 读取矢量数据

R中有多个工具包可以读取矢量数据,常用的有maptools中的readShapeSpatial()系列函数,rgdal中的readOGR()sf中的st_read(),前两个函数读取的文件以Spatial*DataFrame(sp)格式保存,最后一个函数读取的文件以sf格式保存。

准备示例文件:

library(tidyverse)
library(sf)
nc <- st_read(system.file("shape/nc.shp", package = "sf"))
nc2 <- mutate(nc, AREA = "面积")

# 自定义文件夹位置
st_write(nc, "G:/北卡罗来纳州.shp", delete_layer = T) # 文件名含中文
st_write(nc2, "G:/nc2.shp", delete_layer = T) # 文件内含中文
st_write(nc, "G:/nc.shp", delete_layer = T) # 不含中文

1.1 readShapeSpatial()

library(maptools)

sp11 <- readShapeSpatial("G:/北卡罗来纳州.shp") # 文件名含有中文字符,无法运行
sp12 <- readShapeSpatial("G:/nc2.shp") # 文件名无中文字符,文件内容含有中文字符,可以运行
sp13 <- readShapeSpatial("G:/nc.shp") # 文件名和文件内容均无中文字符,可以运行

readShapeSpatial()是一个通用函数,根据要素类型,还可以使用readShapePoints()readShapeLines()readShapePoly()等子函数。

这个函数相比于另外两个函数存在诸多缺点,已经被停止维护了,使用时会出现以下提示:

readShapeSpatial is deprecated; use rgdal::readOGR or sf::st_read

而对于中国用户来说,其最大的缺点可能就是不能读取以中文命名的文件了;若只是属性表中含有中文字符也可以读取。

1.2 readOGR()

library(rgdal)

sp21 <- readOGR(dsn = "G:/", layer = "北卡罗来纳州",
                stringsAsFactors = F,
                use_iconv = TRUE,
                encoding = "UTF-8")
sp22 <- readOGR(dsn = "G:/", layer = "nc2",
                stringsAsFactors = F,
                use_iconv = TRUE,
                encoding = "UTF-8")
sp23 <- readOGR(dsn = "G:/", layer = "nc",
                stringsAsFactors = F)
class(sp23) # 查看数据类型
# 部分输出结果
> class(sp23) # 查看数据类型
[1] "SpatialPolygonsDataFrame"
attr(,"package")
[1] "sp"

readOGR()函数相比于readShapeSpatial()实用性更强,但也存在很多缺点:

  • 第一,调用参数过多。dsn参数指定文件夹路径,layer参数指定文件名,且不带拓展名;

  • 第二,可以读取包含中文字符的文件,但是要调用额外的参数。首先需要将use_iconv参数设置为TRUE,再设置encoding参数为UTF-8;

  • 第三,运行速度相比st_read()函数慢得多。

1.3 st_read()

library(sf)

sf11 <- st_read("G:/北卡罗来纳州.shp")
sf12 <- st_read("G:/nc2.shp")
sf13 <- st_read("G:/nc.shp")
class(sf13)
# 部分输出结果
> class(sf13)
[1] "sf"         "data.frame"

可以看出,st_read()函数相比于另外两个函数调用格式简单地多,运行速度也更快。

st_read()sf工具包中还有一个别名函数read_sf(),其使用方式与st_read()差不多,主要区别是它读取数据后以tibble格式储存。

library(sf)

sf21 <- read_sf("G:/北卡罗来纳州.shp")
sf22 <- read_sf("G:/nc2.shp")
sf23 <- read_sf("G:/nc.shp")
class(sf23)
# 部分输出结果
> class(sf23)
[1] "sf"         "tbl_df"     "tbl"        "data.frame"

2 两种数据格式的转换

sf格式数据具有简洁、易于理解等诸多优点,已经被广泛使用。然而,目前R中的许多空间处理方法仍然只能针对sp格式的数据进行操作,因此有时需要进行两种数据格式的转换。具体方法见以下代码:

library(sf)
world <- spData::world # 样本数据
class(world)

# From sf to sp
# 方法1:使用基础包中的as函数
sp.01 <- as(world, "Spatial")
class(sp.01)
# 方法2:使用sf包中的as_Spatial函数
sp.02 <- as_Spatial(world)
class(sp.02)

# From sp to sf
# 方法1:使用基础包中的as函数
sf.01 <- as(sp.01, "sf")
class(sf.01)
# 方法2:使用sf包中的st_as_sf函数
sf.02 <- st_as_sf(sp.01)
class(sf.02)

3 保存数据到本地

如果要将空间矢量数据以shp格式保存在本地,可以使用sf中的st_write()函数或它的别名函数wrtite_sf()

st_write(world, "G:/world.shp")
write_sf(world, "G:/world2.shp")

需要注意的是,st_write()在保存前需要将该文件夹下的同名文件删掉或重命名,否则会报错;或者设置参数delete_layer为TRUE:

st_write(world, "G:/world.shp", delete_layer  = TRUE)

write_sf的该参数默认为TRUE,无需修改。

 

 

 

  • 22
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值