裁剪 SpatialPolygonsDataFrame

28

我有两个 SpatialPolygonsDataFrame 文件:dat1, dat2

extent(dat1)
class       : Extent 
xmin        : -180 
xmax        : 180 
ymin        : -90 
ymax        : 90 


extent(dat2)
class       : Extent 
xmin        : -120.0014 
xmax        : -109.9997 
ymin        : 48.99944 
ymax        : 60 

我想使用dat2的范围裁剪dat1文件,但我不知道如何操作。我之前只用过“crop”函数处理栅格文件。

当我尝试用这个函数处理我的当前数据时,出现了以下错误:

> r1 <- crop(BiomassCarbon.shp,alberta.shp)
Error in function (classes, fdef, mtable)  : 

 unable to find an inherited method for functioncropfor signature"SpatialPolygonsDataFrame"’

这是没有希望的,需要处理涉及dat1和dat2的问题细节,或者其他相关事项。 - mdsumner
4个回答

65

简化方法添加于2014-10-9:

raster::crop()可用于裁剪Spatial*(以及Raster*)对象。

例如,以下是如何使用它来裁剪SpatialPolygons*对象的示例:

## Load raster package and an example SpatialPolygonsDataFrame
library(raster) 
data("wrld_simpl", package="maptools")

## Crop to the desired extent, then plot
out <- crop(wrld_simpl, extent(130, 180, 40, 70))
plot(out, col="khaki", bg="azure2")
翻译后的内容:

原始(仍然可用)答案:

使用rgeos函数gIntersection()可以使这个过程变得非常简单。

以mnel的不错示例为起点:

library(maptools)
library(raster)   ## To convert an "Extent" object to a "SpatialPolygons" object.
library(rgeos)
data(wrld_simpl)

## Create the clipping polygon
CP <- as(extent(130, 180, 40, 70), "SpatialPolygons")
proj4string(CP) <- CRS(proj4string(wrld_simpl))

## Clip the map
out <- gIntersection(wrld_simpl, CP, byid=TRUE)

## Plot the output
plot(out, col="khaki", bg="azure2")

在此输入图片描述


1
感谢提供代码示例。当我发表回复时,我没有时间。+1 为您使用栅格包创建边界多边形的 clever 解决方案。 - Jeffrey Evans
1
@JeffreyEvans -- 是的。我发现rastersp更好地提供了用户友好的转换函数/方法。我欣赏sp作者可能希望保持其包的简洁和轻量级(因为它旨在支撑许多其他包),但我仍然希望他们最终添加更多实用函数。 - Josh O'Brien
1
整洁: as(extent(130, 180, 40, 70), "SpatialPolygons") 谢谢! - geotheory
裁剪很好 - 但是在光栅中是否有一个反向裁剪,它可以使用第二个形状文件的反向来完成相同的操作? - jebyrnes
@jebyrnes 请查看?raster::erase中的示例,了解一种实现方式。 - Josh O'Brien

7
这里有一个使用rgeos的示例,以世界地图为例。
这个示例来自Roger Bivand在R-sig-Geo邮件列表上的讨论。Roger是sp软件包的作者之一。
以世界地图为例。
library(maptools)

data(wrld_simpl)

# interested in the arealy bounded by the following rectangle
# rect(130, 40, 180, 70)

library(rgeos)
# create  a polygon that defines the boundary
bnds <- cbind(x=c(130, 130, 180, 180, 130), y=c(40, 70, 70, 40, 40))
# convert to a spatial polygons object with the same CRS
SP <- SpatialPolygons(list(Polygons(list(Polygon(bnds)), "1")),
proj4string=CRS(proj4string(wrld_simpl)))
# find the intersection with the original SPDF
gI <- gIntersects(wrld_simpl, SP, byid=TRUE)
# create the new spatial polygons object.
out <- vector(mode="list", length=length(which(gI)))
ii <- 1
for (i in seq(along=gI)) if (gI[i]) {
  out[[ii]] <- gIntersection(wrld_simpl[i,], SP)
  row.names(out[[ii]]) <- row.names(wrld_simpl)[i]; ii <- ii+1
}
# use rbind.SpatialPolygons method to combine into a new object.
out1 <- do.call("rbind", out)
# look here is Eastern Russia and a bit of Japan and China.
plot(out1, col = "khaki", bg = "azure2")

enter image description here


很棒的回答。gIntersection()使这比gIntersects()更简单。 - Josh O'Brien

1

您不能在sp多边形对象上使用crop。您需要创建一个表示dat2 bbox坐标的多边形,然后可以在rgeos库中使用gIntersects。

编辑:此评论是针对2012年版本的,现在不再适用。


0

看到了吗?crop

corp(x, y, filename="", snap='near', datatype=NULL, ...)

x Raster* 对象

y Extent 对象,或者任何可以提取 Extent 对象的对象(详见详情)

您需要使用 raster 包中的 rasterize 函数对第一个 SpatialPolygon 进行栅格化处理。

我创建了一些数据来展示如何使用 rasterize:

n <- 1000
x <- runif(n) * 360 - 180
y <- runif(n) * 180 - 90
xy <- cbind(x, y)
vals <- 1:n
p1 <- data.frame(xy, name=vals)
p2 <- data.frame(xy, name=vals)
coordinates(p1) <- ~x+y
coordinates(p2) <- ~x+y

如果我尝试:

 crop(p1,p2)
 unable to find an inherited method for functioncropfor signature ‘"SpatialPointsDataFrame"’

现在使用光栅化

r <- rasterize(p1, r, 'name', fun=min)
crop(r,p2)

class       : RasterLayer 
dimensions  : 18, 36, 648  (nrow, ncol, ncell)
resolution  : 10, 10  (x, y)
extent      : -180, 180, -90, 90  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 
data source : in memory
names       : layer 
values      : 1, 997  (min, max)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接