简体   繁体   English

如何在R中用多边形裁剪WorldMap?

[英]How to clip WorldMap with polygon in R?

I have imported a world map dataset from www.GADM.org using the R package raster.我使用 R 包栅格从www.GADM.org导入了一个世界地图数据集。 I would like to clip it to a polygon I create to reduce the size of the map.我想将它剪辑到我创建的多边形上以减小地图的大小。 I can retrieve the data and I can create the polygon no problem, but when I use the 'gIntersection' command I get an obscure error message.我可以检索数据,我可以创建多边形没有问题,但是当我使用“gIntersection”命令时,我收到一条模糊的错误消息。

Any suggestions on how to clip my World Map dataset?关于如何剪辑我的世界地图数据集的任何建议?

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 Message:错误信息:

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 RGEOSBinTopoFunc(spgeom1, spgeom2, byid, id, "rgeos_intersection") 中的错误:几何集合可能不包含其他几何集合此外:警告消息:在 RGEOSBinTopoFunc(spgeom1, spgeom2, byid, id, "rgeos_intersection") 和 spge:有不同的 proj4 字符串

You don't need to use PBS (I have learnt this the hard way, as the r-sig-geo link posted by @flowla was a question originally posted by me!).你不需要使用 PBS(我已经通过艰难的方式学到了这一点,因为@flowla 发布的r-sig-geo链接是我最初发布的一个问题!)。 This code shows how to do it all in rgeos, with thanks to various different postings from Roger Bivand.这段代码展示了如何在 rgeos 中完成这一切,感谢 Roger Bivand 发布的各种不同的帖子 This would be the more canonical way of subsetting, without resorting to coercion to PolySet objects.这将是更规范的子集化方式,无需强制转换为 PolySet 对象。

The reason for the error message is that you can't gIntersection on a collection of SpatialPolygons, you need to do them individually.错误消息的原因是您不能对 SpatialPolygons 的集合进行 gIntersection,您需要单独执行它们。 Find out which ones you want using gIntersects .使用gIntersects找出您想要的gIntersects I then subset each country polygon using gIntersection .然后我使用gIntersection每个国家/地区多边形进行子集gIntersection I had a problem passing a list of SpatialPolygons objects back to SpatialPolygons, which turns the croppped shapefiles into SpatialPolygons, which was because not all cropped objects were of class SpatialPolygons .我在将 SpatialPolygons 对象列表传递回 SpatialPolygons 时遇到了问题,这会将裁剪后的 shapefile 转换为 SpatialPolygons,这是因为并非所有裁剪的对象都属于SpatialPolygons class Once we excluded these everything works fine.一旦我们排除了这些,一切正常。

# 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)

在此处输入图片说明

If you can, I recommend you look at naturalearthdata .如果可以,我建议您查看naturalearthdata They have high quality shapefiles that are kept up-to-date and are constantly checked for errors (since they are open source if you find an error do email them).他们有高质量的 shapefile,这些文件会保持最新状态,并且会不断检查错误(因为它们是开源的,如果您发现错误,请通过电子邮件发送给他们)。 Country boundaries are under the Cultural buttons.国家边界位于文化按钮下。 You will see they are also a bit more lightweight and you can choose a resolution appropriate for your needs.您会发现它们也更轻巧,您可以选择适合您需要的分辨率。

How about a little intermediate step?稍微中间步骤怎么样? I adopted the following code mainly from R-sig-Geo and I think it should do the trick.我主要从R-sig-Geo 中采用了以下代码,我认为它应该可以解决问题。 You'll need both 'maptools' and 'PBSmapping' packages, so make sure you've got them installed.您将需要“maptools”和“PBSmapping”软件包,因此请确保已安装它们。 Here's my code:这是我的代码:

# 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)

I just tested it and it worked without any problems.我刚刚测试了它,它没有任何问题。 It took some computation time to transform SpatialPolygons to PolySet, though.不过,将 SpatialPolygons 转换为 PolySet 需要一些计算时间。

Cheers, Florian干杯,弗洛里安

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM