NJUYJX的个人博客分享 http://blog.sciencenet.cn/u/NJUYJX

博文

R语言sp包学习笔记

已有 9600 次阅读 2018-1-20 19:09 |个人分类:R语言|系统分类:科研笔记

sp包中定义几个重要的类别(class)

1. Spatial Objects,只有两个成分(slots):

(1) 边界(bounding box),数字坐标的矩阵(a matrix of numerical coordinates with column names),表明这个空间数据所覆盖的范围。大部分情况下是根据子类别(subclass)自动生成的,不需要手动取标明。

(2) 坐标参考系统(CRS, coordinate reference system),可以设置为缺失‘missing’,CRS(as.character(NA))


有必要对CRS这个slot进行一些简要介绍。它的类别class属于字符类,必须符合PROJ.4的字符串格式。


2. SpatialPoints Objects

SpatialPoints这一个类型是Spatial最重要的一个子类之一。点的地理坐标(geographic coordinates)可以精确表示一个点在球体上的具体位置。但是我们知道地球不是一个完美的球体,而是一个椭圆。所以这些坐标点需要椭圆模型(ellpsoid model)的修正,最常用的就是世界大地测量系统(World Geodetic System 1984)。另外,我们的常识知道,点的地理坐标包括经纬度,纬度从-90到90度,经度从0到360度或-180到180度。纬度相对来说是固定的,但是经度则还与子午线(prime meridian)的选择有关,最常用的就是伦敦的格林威治。还有一个概念叫地球基准面(datum),比较有趣的解释是,把地球拟作椭圆仍然是一个抽象的简化,其实比作凹凸不平的马铃薯是更加贴切的。所以大地基准面就规定了如何在XYZ三个方向调整或缩放,以使得椭圆能够更逼近马铃薯这个表面。


相对于Spatial类,SpatialPoints更多了一个slot,即坐标coordscoords的类别是矩阵matrix。用summary函数可以简要看到边界bbox,对象是否被投影whether the object is projected(需要注意,如果在proj4string这个slot里说明了投影方法,比如“+proj4 = longlat“,那么这里会显示FALSE,不用感到惊讶),有多少个空间点(即坐标矩阵有多少行)


另外一个要注意的:在R语言里,类别的划分不是原子态的(atomic)。这句话怎么理解呢,就是说sp包里不存在SpatialPoint这一class,SpatialPoints这一class也不是在SpatialPoint上拓展出来的。SpatialPoints类里当然可以只包含一个空间点,但是并不意味着有SpatialPoint这一类别。(没必要再多设计一个类别取概括单独的点,其实和英语的单复数变换有关,中国人一般不会有这种理解困扰)


生成SpaitialPoints最常见的方法即利用SpatialPoints()函数,给已有坐标矩阵整合投影系统CRS。如:

data_sp <- SpatialPoints(data_mat, proj4string = CRS)



接下来介绍几个常用的函数

(1) bbox()  提取对象的边界,结果第一行是从西到东的坐标范围;第二行是从南到北的坐标范围;

(2) proj4string()  提取投影字符串。此外还可以对proj4string进行赋值,如proj4string(sp.object) <- CRS(as.character(NA))

(3) coordinates()  提取坐标点矩阵。我们可以对矩阵取子集,得出符合要求的坐标点,如coordinates(sp.object)[c(1,3,5), ]


除此之外,我们可以利用下标直接引用SpatialPoints对象,即利用中括号[]精确引用,这个时候我们是把坐标值看作一个实体,保留原坐标,但生成一个新的边界(很好理解吧)。比如直接sp.object[c(1,3,5), ]。当然中括号[]里也可以放负值,即去掉相应点。(注意,这里取子集,中括号里的都是行操作,不要误用列操作)


2.1 SpatialPoints的衍生品SpatialPointsDataFrame数据类别

定义出这一衍生品的意义是,让SpatialPoints类数据对象能够像数据框一样被R语言使用者方便操作(behave like a data.frame)。


首先,对于地理数据的一个常见操作,即将数据框中的信息(如坐标点的名称、标签等)与地理坐标一一对应。在两个不同数据源需要进行合并的时候,我们经常会面对这一情况。SpatialPointsDataFrame就是为了解决这个问题而生的,它是这些空间点信息的一个大容器container。


构造SpatialPointsDataFrame对象有不同的方法,常见的包括基于坐标点矩阵和已有数据框之间的直接合并。如果坐标点矩阵有行名(row names),match.id这一函数选项为TRUE,那么矩阵的行名将和数据框对应行名将自动进行比较,如果匹配上,则连接两者,并在适当情况下reorder数据框的顺序(key point!调整的是数据框的顺序,生成一个SpatialPointsDataFrame对象;如果没能匹配上,则不会生成任何SpatialPointsDataFrame对象。如

data_spdf <- SpatialPointsDataFrame(coord_mat, data_df, proj4string = CRS, match.ID = TRUE)

我们在对SpatialPointsDataFrame对象进行操作时,我们可以:

(1) 用中括号[]直接引用,这个时候会生成一个新的SpatialPointsDataFrame对象(注意是新的,和之前提到的SpatialPoints取子集一样

(2) 用指针''$''引用,这个时候会返回你所指向的数据框。这个是对传统R类型的极力模仿。

(3) 有一个实现与$同样效果的定位语句:[["colume name"]],在Bivand的书中经常会看到。


我们最后来看一下SpatialPointsDataFrame对象所包含的slots。

除了SpatialPoints对象所包含的 bbox,proj4string,coords之外,SpatialPointsDataFrame对象另包含了data,用来以数据框的形式存储空间点的数据信息。


除了通过连接坐标点矩阵与数据框之外,还可以直接在SpatialPoints对象的基础之上,利用SpatialPointsDataFrame()函数,将数据框整合进原SpatialPoints对象之内。


还有一种方式,就是将坐标信息赋予原数据框格式的对象,这一方法会修改原数据框

比如利用坐标分配函数coordinates(data_df) <- coords_df  proj4string(data_df) <- CRS  


3. SpatialLines Objects

在介绍SpatialLines对象之前,先介绍Line对象和Lines对象,这两者不是sp包中特有的对象。对于R语言sp包中的Line对象,本质就是一个2D坐标的矩阵,且不包含空值。两者之间的关系可以总结为:A list of Line objects forms the Lines slots of a Lines object,



SptialLines对象在Line与Lines的基础之上,又包含了边界和投影等信息


Bivand的书中举了一个例子,将maps包的世界地图用maptools包中的map2SpatialLines函数提取成SpatialLines对象



在检查这些对象成分的时候,最常用的一种方法就是结合sapply、lapplyslot函数。其中,sapply和lapply函数会把规定函数应用于第一个对象上,如:

Lines_len <- sapply(slot(SLJapan, "lines"), function(x) length(slot(x, "Lines")))

这条语句的功能即返回Lines这一成分的长度——包含了多少个Line对象。你可能注意到了大小写的差异,在SLJapan里,对应的slot是"lines",因为对于SpatialLines这个对象里,在Lines对象里,对应的slot是“Lines”,是不是很绕!我自己也有点晕。


SpatialLines在可视化或者数据分析中可能并不常用,比如在画了行政边界后,相对不同的行政区着色,用SpatialLines着色是不可能的。但是,线段这种去除信息和细节的效果也是有其自身的用途的,比如很多包都是line thinning的函数。


2.6 SpatialPolygons

在早期的S语言与后续的R语言中,对空间多边形的定义均为:闭合的线,即一系列首位相同的点坐标(a sequence of points coordinates where the first point is the same as the last point)。


和SpatialLines对象一样,我们在讨论SpatialPolygons对象之前,先从Polygon这个最基础的对象说起。Polygon从Line拓展而来,但要包含更多的slots。


具体包括:

1) labpt (label point, taken as the centriod of the polygon)

2) area (the area of the polygon in the metric of the coordinates)

3) hole (whether the polygon is declared as a hole or not)

4) ringDir (the ring direction of the polygon)


接着看一下Polygons对象,和Lines对象很像,Polygons包括了其他slots:

1) Polygons (符合条件的polygon的列表)

2) ID (an identifying character string)

3) labpt (a label point taken as the label point of the constituent polygon with the largest area)

4) plotOrder (used as helper in plotting using R graphic function, set the order in which the polygons belonging to the object should be plotted)

5) area (the gross area of the polygon, equal to the sum of all the constituent polygons)


最后就是最高一层的SpatialPolygons对象,在Polygons的基础上又补充了bbox和projection。

和Polygons对象类似,SpatialPolygons专门设置了一个画图顺序slot (defined by default to plot its member polygons, stored in the polygons (这里又是小写)as a list of Polygons, in order of gross area, from largest to smallest)


2.6.1 SpatialPolygonsDataFrame对象

和其他的空间对象一样,Spatial*DataFrame将空间对象与数据连接起来(bring together the spatial representations of polygons with data)。接下来一句话非常绕:The identifying tags of the Polygons in the polygon slot of a SpatialPolygons objects are matched with the row names of the data frame to make sure that the correct data rows are associated with the correct spatial objects .具体原理和SpatialPointsDataFrame原理是一样的。


2.6.2 Holes and Ring Direction

这两个slots的主要解决R语言相对于GIS在处理空间对象时候的一些困难。在传统的GIS向量中,多边形之间的边界被存储为节点(nodes)之间的弧(arc)。这样两个多边形之间的关系很难区分,比如对于包含关系的陆地和湖泊,或者海洋与陆地,需要一些其他的属性指明区分。


sp包中所采用的方法就是采用了两个标志,一个slot是hole,用逻辑值标明多边形是否包含在另一个多边形内部的;第二个slot是ring direction,顺时针方向表示不是hole,逆时针表示是hole。This is needed because the non-topological representation of polygons have no easy way of knowing that a polygon represents an internal boundary of an enclosing polygon, a hole, or lake.


书中举了一个manitoulin湖的例子,可是找了半天没找到这个数据在哪里。后来在google上找了半天才终于找到。

load("high.RData")

manitoulin_sp <- high$SP

2.7 SpatialGrid and SpatialPixel

定义网格图所需要的信息要比别的图形要少很多。一旦每一个中心点的位置(single point of origin)明确了,再提供单元格的分辨率(resolution)和行列数(the numbers of rows and columns),就可以确定网格范围了(extent of the gird)。

这一对象常用来以小矩形为单元存储数据is used widely for storing data in regular rectangular cells。

比如:数字高程(Digital Elevation Model, DEM)、卫星影像(Satellite Imagery)、点测量数据差值(Interpolated data from point measurement)、图像处理(Image processing)


和之前介绍点线面数据一样,我们先介绍GridTopology对象.

其包括三个slots

(1) cellcentre.offset  (numeric) 顾名思义,就是网格的中心点位置

(2) cellsize  (numeric) 网格大小,即分辨率

(3) cells.dim  (integer),纬度大小,就是每个方向有多少个格子


在GridTopology的基础上,就可以生成SpatialGrid格式的点,把CRS传递给GridTopology对象即可,这个时候bbox就可以自动生成。SpatialGridDataFrame原理和其他形状是一样的。整个SpatialGridDataFrame对象的大小几乎全部是由"data" slot提供的。








https://wap.sciencenet.cn/blog-3376545-1095933.html

上一篇:R语言数据清洗
下一篇:R语言sp包学习笔记(2)——Chapter3 Visualizing Spatial Data

2 黄仁勇 王秀萍

该博文允许注册用户评论 请点击登录 评论 (0 个评论)

数据加载中...

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2021-12-4 10:25

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部