如何在R中剪切带有多边形的世界地图?

时间:2013-04-08 14:14:55

标签: r gis polygon crop clip

我使用R包栅格从www.GADM.org导入了世界地图数据集。我想将其剪切为我创建的多边形以减小地图的大小。我可以检索数据,我可以创建多边形没问题,但是当我使用'gIntersection'命令时,我得到一个模糊的错误信息。

有关如何剪辑我的世界地图数据集的任何建议吗?

library(raster)
library(rgeos)

## Download Map of the World ##
WorldMap <- getData('countries')

## Create the clipping polygon
clip.extent <- as(extent(-20, 40, 30, 72), "SpatialPolygons")
proj4string(clip.extent) <- CRS(proj4string(WorldMap))

## Clip the map
EuropeMap <- gIntersection(WorldMap, clip.extent, byid = TRUE)

错误讯息:

Error in RGEOSBinTopoFunc(spgeom1, spgeom2, byid, id, "rgeos_intersection") : 
  Geometry collections may not contain other geometry collections
In addition: Warning message:
In RGEOSBinTopoFunc(spgeom1, spgeom2, byid, id, "rgeos_intersection") :
  spgeom1 and spgeom2 have different proj4 strings

2 个答案:

答案 0 :(得分:9)

你不需要使用PBS(我已经学到了很多,因为@flowla发布的r-sig-geo链接是我最初发布的一个问题!)。此代码显示了如何在rgeos中完成所有操作,感谢Roger Bivand的various不同postings。这将是更典型的子集化方法,而不需要对PolySet对象进行强制。

错误消息的原因是您无法对SpatialPolygons集合进行gIntersection,您需要单独执行它们。使用gIntersects找出您想要的内容。然后我使用gIntersection对每个国家多边形进行子集化。我在将SpatialPolygons对象列表传递回SpatialPolygons时遇到了问题,它将裁剪的shapefile转换为SpatialPolygons,这是因为并非所有裁剪的对象都是class SpatialPolygons。一旦我们排除了这些,一切正常。

# This very quick method keeps whole countries
gI <- gIntersects(WorldMap, clip.extent, byid = TRUE )
Europe <- WorldMap[which(gI), ]
plot(Europe)


#If you want to crop the country boundaries, it's slightly more involved:
# This crops countries to your bounding box
gI <- gIntersects(WorldMap, clip.extent, byid = TRUE)
out <- lapply(which(gI), function(x){ 
        gIntersection(WorldMap[x,], clip.extent)
   })

# But let's look at what is returned
table(sapply(out, class))
#   SpatialCollections    SpatialPolygons 
#                    2                 63 


# We want to keep only objects of class SpatialPolygons                 
keep <- sapply(out, class)
out <- out[keep == "SpatialPolygons"]


# Coerce list back to SpatialPolygons object
Europe <- SpatialPolygons(lapply(1:length(out), function(i) {
          Pol <- slot(out[[i]], "polygons")[[1]]
          slot(Pol, "ID") <- as.character(i)
          Pol
   }))

plot(Europe)

enter image description here

如果可以,我建议您查看naturalearthdata。它们具有高质量的shapefile,可以保持最新并不断检查错误(因为如果发现错误,它们是开源的,请发送电子邮件)。国家边界位于 Cultural 按钮下。你会发现它们的重量也更轻,你可以选择适合你需要的分辨率。

答案 1 :(得分:2)

一点中间步骤怎么样?我主要从R-sig-Geo采用了以下代码,我认为应该这样做。你需要'maptools'和'PBSmapping'包,所以一定要安装它们。这是我的代码:

# Required packages
library(raster)
library(maptools)
library(PBSmapping)

# Download world map
WorldMap <- getData('countries')
# Convert SpatialPolygons to class 'PolySet'
WorldMap.ps <- SpatialPolygons2PolySet(WorldMap)
# Clip 'PolySet' by given extent
WorldMap.ps.clipped <- clipPolys(WorldMap.ps, xlim = c(-20, 40), ylim = c(30, 72))
# Convert clipped 'PolySet' back to SpatialPolygons
EuropeMap <- PolySet2SpatialPolygons(WorldMap.ps.clipped, close_polys=TRUE)

我刚试过它,它没有任何问题。但是,将SpatialPolygons转换为PolySet需要一些计算时间。

干杯, 弗洛里安