一个R语言中操纵矢量空间数据的标准化工具—sf

2020-06-16 00:00:00 数据 函数 对象 空间 几何
​注: 本文是R语言sf包的核心开发者和维护者——来自德国明斯特大学的地理信息学教授:Edzer Pebesma 的一篇关于sf包的简介,发表于2018年7月的R语言期刊,主要讲述了sf的定位、功能、开发现状及现存问题和今后展望,sf包是一个非常了不起的工具,在R语言中引入了空间数量分析领域通用的标准规范(simple feature),结合tidyverse工具箱组合,R语言中处理、转化与绘制地理空间数据的复杂度降了一个数量级。

by Edzer Pebesma摘要Simple features是一种在计算机中编码矢量空间数据(点、线、面等)的标准化方法。sf包在R语言中引入了simple features对象,它基本具备和sp、rgeos、rgdal一样的矢量空间数据处理能力。本文主要描述此包的基本功能,其在R语言诸多扩展生态系统中的地位,以及在连接R语言与其他空间计算系统中的潜在价值。

"Simple features" 究竟是什么?

我们可以把“Features”看做是一种包含特定空间位置或范围的“事物”或对象;Featrue gemetry是指某种空间几何特征(位置或范围),或者你也可以直接把其当成是一个点、点集合、线、线集合、多边形、多边形集合,甚至是以上多种对象的结合。简单来说,simple features就是线集合、多边形集合的特征(这些线集合或者多边形集合是由很多点连接的直线段构成的)。Features 还包含有其他典型属性(如时间、颜色、名称、质量),我们称之为特征属性。并非所有的空间现象都可以被轻易称为“事物”或“对象”。某些连续性现象:比如水温或者海拔等诸如此类的,我们好把其看成是来自于连续空间(或时间)上的映射函数(Scheider et al., 2016),这些也经常被作为栅格数据而非矢量数据(点集合、线集合、多边形集合)。Simple feature 对象(Herring,2011)是呈现、编码矢量空间数据的国际通用标准,主要用于呈现点、线、多边形等几何对象(IOS,2004)。它被广泛用于各种空间数据库系统(Herring,2010),GeoJSON(Butler et al.,2016),GeoSPL(Perry and Herring,2012),以及开源地理信息工具库:如GDAL(Warmerdam,2008),GEOS(GEOS Development Team,2017) 和liblwgeom(一个PostGIS的附加模块,Obe and Hsu(2015))。

一个新包的价值

sf包(Pebesma,2018)是R语言中一个读取、写入、操纵、计算simple features对象的工具包。它几乎重塑了sp包中所有矢量空间数据(点集合、线集合、多边形集合等)处理功能(Pebesma and Bivand,2005;Bivand et al.,2013),rgdal ( Bivand et al.,2017) 和 rgeos ( Bivand and Rundel,2017)。由于sp包具有约400个直接的反向依赖和几千个间接依赖,所以很有必要重写一个包来替代它。首先,在sp包的开发期间,simple features标准还尚未出现,ESRI shapefile那时在矢量空间数据的存储和转换上来处于统治地位。但是由于ESRI shapefile缺乏清晰开放的标准,其本身混乱、繁多的配置文件及其在呈现空间数据上的诸多缺陷,给sp包造成了不利影响,比如在呈现多边形集合上的孔洞时,盲目的使用封闭外边界来标记孔洞。这种方式严重影响图形绘制,阻碍其与其他同类型工具库之间的兼容性。simple feature 格式标准目前已经被广泛采纳,但是sp包仍然习以为常的将矢量空间数据强制转化为R的内部对象。这也意味着你无法灵活的进行双向数据操作。比如:导入数据、操纵数据、导出数据后才能得到同样的几何对象。但对于sf而言,这根本就是不是问题。另一个重要原因是R语言在读写空间数据(GDAL)以及操纵空间几何对象(GEOS)时重度依赖的外部扩展库均以对simple feature标准给予了强有力的支持。除此之外,sp和当前比较流行的数据操纵工具箱:如tidyverse(Wickham et., 2017)和 ggplot2(wickham,2016)等之间的兼容性较差。

  • tidyverse 包不仅把操纵对象当做是一个数据框(然而sp 对象则是通过提供方法函数来实现),而且把对象视作一个长度相等的向量组成的列表,这一点儿sp包望尘莫及。
  • 在使用ggplot2绘图时,先利用fortify函数将sp对象转化成数据框(该数据框里存放着每一个多边形构成点的信息),以此来尝试“简化”多边形对象,这样既不优雅,也不高效。


基本规范

数据类型

sf包的主要类型如下:

  • “sf”: 一个数据框(或者tl_df):包含一到 多个空间几何对象列(通常由一组与数据框等长的列表组成)、一个用于标识当前空间几何对象列(sfc类)的属性(sf_column),
  • "sfc": 一个由一组空间几何属性组成的列表列
  • "sfg":一个空间几何列表列中的任一个元素(一个几何要素)
  • "crs": 一个坐标参考系统(CRS),作为“sfc”对象的性质存储除了“sfg”对象之外,以上所有类型均可看做列表。“sfg”对象可看做是其他类型的子类,这些类主要有以下几种存储格式:

POINT:一个单点组成的数值型向量

MULTIPOINT:每行由多点组成的数值矩阵

LINESTRING:每行由多点组成的数值矩阵

POLYGON:多个数据矩阵(每行由多点组成)组成的列表(多边形边界内部可能嵌套若干个孔洞)

MULTILINRSTRING:多个数值矩阵(每行由多点组成)组成的列表

MULTIPLOYGON:POLYGON结构组成的list

GEOMETRYCOLLECTION: 一个或多个以上几何对象组成的结构。所有的几何对象都具有空值,表示几何对象的缺失(或者NA)。


函数与方法


CategorygoryFunctions


binary predicatesst_contains,st_contains_properly,st_convered_by,st_covers,st_crosses,st_disjoint,st_equals,st_equals_exact,st_intersects,st_is_within_distance,st_within,st_touches,st_overlapsbinary operationsst_relate,st_distanceunary operationsst_dimension,st_area,st_length,st_is_longlat,st_is_simple,st_is_valid,st_jitter,st_geohash,st_geometry_type,st_sample,st_line_sample,st_join,st_interpolate_aw,st_make_grid,st_graticule,st_extSoftVersion,raw_ToHex,st_proj_infosettersst_set_agr,st_set_crsconstructorsst_sfc,st_sf,st_as_sf,st_as_sfc,st_point,st_multipoint,st_linestring,st_multilinestring,st_polygon,st_multipolygon,st_geometrycollection,st_combine,st_bind_colsin & outputst_read,st_read_db,st_write,st_write_db,read_sf,write_sf,st_drivers,st_layersplottingst_viewport,st_wrap_dateline,sf.colors表格 1:来自sf包的功能函数 ,按照函数类别顺序


以上所列函数中,部分函数同时作用于属性和几何对象,比如:aggregate 和 summarize 计算分组统计量。class methods


sfgas.matrix, c, coerce, format, head, Ops, plot, print, st_as_binary, st_as_grob, st_as_text, st_transform, st_coordinates, st_geometry, st_boundary, st_buffer, st_centroid, st_convex_hull, st_difference, st_intersection, st_line_merge, st_make_valid, st_node, st_point_on_surface, st_polygonize, st_segmentize, st_simplify, st_split, st_sym_difference, st_triangulate, st_union, st_voronoi, st_cast, st_collection_extract, st_is, st_zmsfc[, [<-, as.data.frame, c, coerce, format, Ops, print, rep, st_as_binary, st_as_text, st_bbox, st_coordinates, st_crs, st_crs<-, st_geometry, st_precision, st_set_precision, str, summary, st_transform, st_boundary, st_buffer,st_centroid, st_convex_hull, st_difference, st_intersection, st_line_merge, st_make_valid, st_node, st_point_on_surface, st_polygonize, st_segmentize, st_simplify, st_split, st_sym_difference, st_triangulate, st_union, st_voronoi, st_cast, st_collection_extract, st_is, st_zm, obj_sum, type_sumsf[, [[<-, $<-, aggregate, cbind, coerce, merge, plot, print, rbind, st_agr, st_agr<-, st_bbox, st_coordinates, st_crs, st_crs<-, st_geometry, st_geometry<-, st_precision, st_set_precision, st_transform, st_boundary, st_buffer, st_centroid, st_convex_hull, st_difference, st_intersection, st_line_merge, st_make_valid, st_node, st_point_on_surface, st_polygonize, st_segmentize, st_simplify, st_split, st_sym_difference, st_triangulate, st_union, st_voronoi, st_cast, st_collection_extract, st_is, st_zm, anti_join, arrange, distinct, filter, full_join, gather, group_by, inner_join, left_join, nest, mutate, rename, right_join, sample_frac, sample_n, select, semi_join, separate, slice, spread, summarise, transmute, ungroup, unitecrs$, is.na, Ops, print, st_as_text, st_crs表格 2:sf包中的类方法st_interpolate_aw函数可以针对几何对象进行基于面积加权的差值计算(Do et al., 2015)。st_join可以基于空间类型连接成对的表格。sf包的一般方法已经展示在上面表格2中了,其中很多方法主要服务于矢量空间数据的创建、抽取、转换,当然也有很函数属于不经常用到的低频函数。在可能的情况下,方法作用于一个几何对象(sfg)、一个几何对象集合(sfc)或一个带有属性的集合对象集合(sf),同时返回一个相同类的对象。序列化simple featrue对象定义了两个序列化标准:常见文本表现形式(WKT)和二进制文本表现形式(WKB)。常见文本表现形式是日常打印时默认的输出格式,sfc列可以利用st_as_sfc函数从WKT格式的字符串向量中直接读取。

> library(sf)
Linking to GEOS 3.5.1, GDAL 2.1.2, proj.4 4.9.3
> (pt <- st_point(c(0,1)))
POINT (0 1)
> (pol <- st_polygon(list(rbind(c(0,0), c(1,0), c(1,1), c(0,1), c(0,0)))))
POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))
> st_as_sfc("POINT(0 1)") # returns sfc:
Geometry set for 1 feature
geometry type:  POINT
dimension:      XY
bbox:           xmin: 0 ymin: 1 xmax: 0 ymax: 1
epsg (SRID):    NA
proj4string:    NA
POINT (0 1)
    R native simple feature geometries can be written to WKB usingst_as_binary:

> st_as_binary(st_point(c(0,1)))[1] 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0 3f
> st_as_binary(st_polygon(list(rbind(c(0,0), c(1,0), c(1,1), c(0,1), c(0,0)))))
[1] 01 03 00 00 00 01 00 00 00 05 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[26] 00 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00 00 00 00 00 00 00 00 00 00 00
[51] 00 f0 3f 00 00 00 00 00 00 f0 3f 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[76] f0 3f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

相关文章