[GIS] How to perform a true GIS clip of polygons layer using a polygon layer in R

cliplayerspolygonrvector

I would like to do a true GIS Clip in R of soils polygons using a series of single boundary polygons, but I cannot find an R function to properly do it. It should work just like the clip function in ESRI's ArcMap. I've tried the over method in sp package but it doesn't seem to work for polys over polys.

One suggestion was to use the gIntersection in rgeos package as a clip using the following code:

#------------------------------------
library(rgeos)
library(maptools)

#Read layers as SpatialPolygonsDataFrame (both the same Albers projection)
Soils_poly = readShapePoly("Soils_polygons")  #Note - Has 400 polygons
clipper_poly = readShapePoly("clipper_polygon")  #Note - Has 1 polygon

#Try gintersection as clip 
Clipped_polys = gIntersection(Clipper_Tile_poly, Soils_poly)

#-----------------------------------

This takes 5 minutes to run (way too slow) and errors with this:

Error in RGEOSBinTopoFunc(spgeom1, spgeom2, byid, id, drop_not_poly, "rgeos_intersection") :
TopologyException: no outgoing dirEdge found at -721459.77681285271 2009506.5980877089

I also tried this code to check for overlap:

gIntersects(Clipper_Tile_poly, Soils_poly)

and the result was TRUE. clip function in ESRI ArcMap works fine for this data.

Anyone knows of an R function to properly do a clip on spatial polygons using spatial polygons?

Best Answer

The hint provided by @mdsummer of using byid=TRUE works accurately.

See the reproducible example, below:

library(rgeos)
library(sp)

#Create SpatialPlygons objects
polygon1 <- readWKT("POLYGON((-190 -50, -200 -10, -110 20, -190 -50))") #polygon 1
polygon2 <- readWKT("POLYGON((-180 -20, -140 55, 10 0, -140 -60, -180 -20))") #polygon 2

par(mfrow = c(1,2)) #in separate windows
plot(polygon1, main = "Polygon1") #window 1
plot(polygon2, main = "Polygon2") #window 2

polygons side-by-side

polygon_set <- readWKT(paste("POLYGON((-180 -20, -140 55, 10 0, -140 -60, -180 -20),",
                     "(-190 -50, -200 -10, -110 20, -190 -50))"))

par(mfrow = c(1,1)) #now, simultaneously
plot(polygon_set, main = "Polygon1 & Polygon2")

enter image description here

clip <- gIntersection(polygon1, polygon2, byid = TRUE, drop_lower_td = TRUE) #clip polygon 2 with polygon 1
plot(clip, col = "lightblue")

enter image description here

GT <- GridTopology(c(-175, -85), c(10, 10), c(36, 18))
gr <- as(as(SpatialGrid(GT), "SpatialPixels"), "SpatialPolygons")
plot(gr)

enter image description here

clip2 <- gIntersection(clip, gr, byid = TRUE, drop_lower_td = TRUE)
plot(clip2, col = "pink")

enter image description here


Edit:

If one wants to intersect while keeping the attribute data, then one option is the raster::intersect function. See jeb's answer.

Related Question